diff options
Diffstat (limited to 'tcl')
-rw-r--r-- | tcl/board/ti_am261_launchpad.cfg | 25 | ||||
-rw-r--r-- | tcl/board/ti_am263p_launchpad.cfg | 25 | ||||
-rw-r--r-- | tcl/board/ti_am62levm.cfg | 25 | ||||
-rw-r--r-- | tcl/board/ti_mspm0_launchpad.cfg | 14 | ||||
-rw-r--r-- | tcl/target/bl602.cfg | 34 | ||||
-rw-r--r-- | tcl/target/bl602_common.cfg | 143 | ||||
-rw-r--r-- | tcl/target/bl702.cfg | 59 | ||||
-rw-r--r-- | tcl/target/bl702l.cfg | 47 | ||||
-rw-r--r-- | tcl/target/ngultra.cfg | 5 | ||||
-rw-r--r-- | tcl/target/nordic/nrf54l.cfg | 23 | ||||
-rw-r--r-- | tcl/target/renesas_rcar_gen3.cfg | 29 | ||||
-rw-r--r-- | tcl/target/ti_k3.cfg | 43 | ||||
-rw-r--r-- | tcl/target/ti_mspm0.cfg | 199 |
13 files changed, 609 insertions, 62 deletions
diff --git a/tcl/board/ti_am261_launchpad.cfg b/tcl/board/ti_am261_launchpad.cfg new file mode 100644 index 0000000..c6c4609 --- /dev/null +++ b/tcl/board/ti_am261_launchpad.cfg @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ +# +# Texas Instruments AM261 Launchpad +# https://www.ti.com/tool/LP-AM261 +# + +# AM263 Launchpad has an xds110 onboard. +source [find interface/xds110.cfg] + +transport select jtag + +# default JTAG configuration has only SRST and no TRST +reset_config srst_only srst_push_pull + +# delay after SRST goes inactive +adapter srst delay 20 + +if { ![info exists SOC] } { + set SOC am261 +} + +source [find target/ti_k3.cfg] + +adapter speed 250 diff --git a/tcl/board/ti_am263p_launchpad.cfg b/tcl/board/ti_am263p_launchpad.cfg new file mode 100644 index 0000000..96e06fa --- /dev/null +++ b/tcl/board/ti_am263p_launchpad.cfg @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ +# +# Texas Instruments AM263P Launchpad +# https://www.ti.com/tool/LP-AM263P +# + +# AM263P Launchpad has an xds110 onboard. +source [find interface/xds110.cfg] + +transport select jtag + +# default JTAG configuration has only SRST and no TRST +reset_config srst_only srst_push_pull + +# delay after SRST goes inactive +adapter srst delay 20 + +if { ![info exists SOC] } { + set SOC am263p +} + +source [find target/ti_k3.cfg] + +adapter speed 250 diff --git a/tcl/board/ti_am62levm.cfg b/tcl/board/ti_am62levm.cfg new file mode 100644 index 0000000..6debdd4 --- /dev/null +++ b/tcl/board/ti_am62levm.cfg @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/ +# +# Texas Instruments AM62L EVM: +# Links: https://www.ti.com/tool/TMDS62LEVM +# + +# the AM62L3 EVM/SK has an xds110 onboard. +source [find interface/xds110.cfg] + +transport select jtag + +# default JTAG configuration has only SRST and no TRST +reset_config srst_only srst_push_pull + +# delay after SRST goes inactive +adapter srst delay 20 + +if { ![info exists SOC] } { + set SOC am62l +} + +source [find target/ti_k3.cfg] + +adapter speed 2500 diff --git a/tcl/board/ti_mspm0_launchpad.cfg b/tcl/board/ti_mspm0_launchpad.cfg new file mode 100644 index 0000000..132fdc2 --- /dev/null +++ b/tcl/board/ti_mspm0_launchpad.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023-2025 Texas Instruments Incorporated - https://www.ti.com/ +# +# TI MSPM0L1306 LaunchPad Evaluation Kit +# https://www.ti.com/tool/LP-MSPM0L1306 +# TI MSPM0C1104 LaunchPad Evaluation Kit +# https://www.ti.com/tool/LP-MSPM0C1104 +# TI MSPM0G3507 LaunchPad Evaluation Kit +# https://www.ti.com/tool/LP-MSPM0G3507 +# + +source [find interface/xds110.cfg] +adapter speed 10000 +source [find target/ti_mspm0.cfg] diff --git a/tcl/target/bl602.cfg b/tcl/target/bl602.cfg new file mode 100644 index 0000000..d110d3e --- /dev/null +++ b/tcl/target/bl602.cfg @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Bouffalo Labs BL602 and BL604 target +# +# https://en.bouffalolab.com/product/?type=detail&id=1 +# +# Default JTAG pins: (if not changed by eFuse configuration) +# TDO - GPIO11 +# TMS - GPIO12 +# TCK - GPIO14 +# TDI - GPIO17 +# + +if { [info exists CHIPNAME] } { + set BL602_CHIPNAME $CHIPNAME +} else { + set BL602_CHIPNAME bl602 +} + +set CPUTAPID 0x20000c05 + +# For work-area we use DTCM instead of ITCM, due ITCM is used as buffer for L1 cache and XIP +set WORKAREAADDR 0x42014000 +set WORKAREASIZE 0xC000 + +source [find target/bl602_common.cfg] + +# JTAG reset is broken. Read comment of bl602_sw_reset_hbn_wait function for more information +$_TARGETNAME configure -event reset-assert { + halt + + bl602_sw_reset_hbn_wait +} diff --git a/tcl/target/bl602_common.cfg b/tcl/target/bl602_common.cfg new file mode 100644 index 0000000..cf4bc39 --- /dev/null +++ b/tcl/target/bl602_common.cfg @@ -0,0 +1,143 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Script for Bouffalo chips with similar architecture used in BL602 +# based on SiFive E21 core + +source [find mem_helper.tcl] + +transport select jtag + +if { [info exists CPUTAPID ] } { + set _CPUTAPID $CPUTAPID +} else { + error "you must specify a tap id" +} + +if { [info exists BL602_CHIPNAME] } { + set _CHIPNAME $BL602_CHIPNAME +} else { + error "you must specify a chip name" +} + +if { [info exists WORKAREAADDR] } { + set _WORKAREAADDR $WORKAREAADDR +} else { + error "you must specify a work area address" +} + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + error "you must specify a work area size" +} + +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME riscv -chain-position $_TARGETNAME + +riscv set_mem_access sysbus +riscv set_enable_virt2phys off + +$_TARGETNAME configure -work-area-phys $_WORKAREAADDR -work-area-size $_WORKAREASIZE -work-area-backup 1 + +# Internal RC ticks on 32 MHz, so this speed should be safe to use. +adapter speed 8000 + +# Useful functions + +set dmcontrol 0x10 +set dmcontrol_dmactive [expr {1 << 0}] +set dmcontrol_ndmreset [expr {1 << 1}] +set dmcontrol_resumereq [expr {1 << 30}] +set dmcontrol_haltreq [expr {1 << 31}] + +proc bl602_restore_clock_defaults { } { + # Switch clock to internal RC32M + # In HBN_GLB, set ROOT_CLK_SEL = 0 + mmw 0x4000f030 0x0 0x00000003 + # Wait for clock switch + sleep 10 + + # GLB_REG_BCLK_DIS_FALSE + mww 0x40000ffc 0x0 + + # HCLK is RC32M, so BCLK/HCLK doesn't need divider + # In GLB_CLK_CFG0, set BCLK_DIV = 0 and HCLK_DIV = 0 + mmw 0x40000000 0x0 0x00FFFF00 + # Wait for clock to stabilize + sleep 10 +} + +# 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. +proc bl602_sw_reset { } { + # In GLB_SWRST_CFG2, clear CTRL_SYS_RESET, CTRL_CPU_RESET and CTRL_PWRON_RESET + mmw 0x40000018 0x0 0x00000007 + + # 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 system bus access directly with DMI commands, to avoid errors printed by + # OpenOCD about unsuccessful register write. + + # In GLB_SWRST_CFG2, set CTRL_SYS_RESET, CTRL_CPU_RESET and CTRL_PWRON_RESET to 1 + riscv dmi_write 0x39 0x40000018 + riscv dmi_write 0x3c 0x7 + + # We need to wait for chip to finish reset and execute BootROM + sleep 1 + + # 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} ] + + # Set Program Counter to start of BootROM + set_reg {pc 0x21000000} +} + +# On BL602 and BL702, the only way to force chip stay in BootROM (until JTAG attaches) +# is by putting infinity loop into HBN RAM (which is not reset by sw reset), and then +# configure HBN registers, which will cause BootROM to jump into our code early in BootROM. +proc bl602_sw_reset_hbn_wait {} { + # Restore clocks to defaults + bl602_restore_clock_defaults + + # In HBN RAM, write infinity loop instruction + # beq zero, zero, 0 + mww 0x40010000 0x00000063 + # In HNB, set HBN_RSV0 (Status Flag) to "EHBN" (as uint32_t) + mww 0x4000f100 0x4e424845 + # In HBN, set HBN_RSV1 (WakeUp Address) to HBN RAM address + mww 0x4000f104 0x40010000 + + # Perform software reset + bl602_sw_reset + + # Clear HBN RAM, HBN_RSV0 and HBN_RSV1 + mww 0x40010000 0x00000000 + mww 0x4000f100 0x00000000 + mww 0x4000f104 0x00000000 + + # This early jump method locks up BootROM through Trust Zone Controller. + # That means any read of BootROM returns 0xDEADBEEF. + # Only way to reset it, is through JTAG Reset, thus toggling ndmreset in dmcontrol. + riscv dmi_write $::dmcontrol [ expr {$::dmcontrol_dmactive | $::dmcontrol_ndmreset} ] + riscv dmi_write $::dmcontrol [ expr {$::dmcontrol_dmactive} ] +} + +$_TARGETNAME configure -event reset-deassert-post { + # Resume the processor if reset was triggered without halt request + if {$halt == 0} { + riscv dmi_write $::dmcontrol [ expr {$::dmcontrol_dmactive | $::dmcontrol_resumereq} ] + } +} diff --git a/tcl/target/bl702.cfg b/tcl/target/bl702.cfg index 5046cd1..8caf06e 100644 --- a/tcl/target/bl702.cfg +++ b/tcl/target/bl702.cfg @@ -12,62 +12,23 @@ # TDO - GPIO9 # -source [find mem_helper.tcl] - -transport select jtag - if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME + set BL602_CHIPNAME $CHIPNAME } else { - set _CHIPNAME bl702 + set BL602_CHIPNAME bl702 } -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000e05 - -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME riscv -chain-position $_TARGETNAME - -riscv set_mem_access sysbus +set CPUTAPID 0x20000e05 -$_TARGETNAME configure -work-area-phys 0x22020000 -work-area-size 0x10000 -work-area-backup 1 +# For work-area we use DTCM instead of ITCM, due ITCM is used as buffer for L1 cache and XIP +set WORKAREAADDR 0x22014000 +set WORKAREASIZE 0xC000 -# Internal RC ticks on 32 MHz, so this speed should be safe to use. -adapter speed 4000 +source [find target/bl602_common.cfg] -# Debug Module's ndmreset resets only Trust Zone Controller, so we need to do SW reset instead. -# CTRL_PWRON_RESET triggers full "power-on like" reset. -# This means that pinmux configuration to access JTAG is reset as well, and configured back early -# in BootROM. -$_TARGETNAME configure -event reset-assert-pre { +# JTAG reset is broken. Read comment of bl602_sw_reset_hbn_wait function for more information +$_TARGETNAME configure -event reset-assert { halt - # Switch clock to internal RC32M - # In HBN_GLB, set ROOT_CLK_SEL = 0 - mmw 0x4000f030 0x0 0x00000003 - # Wait for clock switch - sleep 10 - - # GLB_REG_BCLK_DIS_FALSE - mww 0x40000ffc 0x0 - - # HCLK is RC32M, so BCLK/HCLK doesn't need divider - # In GLB_CLK_CFG0, set BCLK_DIV = 0 and HCLK_DIV = 0 - mmw 0x40000000 0x0 0x00FFFF00 - # Wait for clock to stabilize - sleep 10 - - # Do reset - # In GLB_SWRST_CFG2, clear CTRL_SYS_RESET, CTRL_CPU_RESET and CTRL_PWRON_RESET - mmw 0x40000018 0x0 0x00000007 - - # Since this full software reset resets GPIO pinmux as well, we will lose access - # to JTAG right away after writing to register. This chip doesn't support abstract - # memory access, so when this is done by progbuf or sysbus, OpenOCD will fail to read - # if write was successful or not, and will print error about that. Since receiving of - # this error is expected, we will turn off log printing for a moment, - set lvl [lindex [debug_level] 1] - debug_level -1 - # In GLB_SWRST_CFG2, set CTRL_SYS_RESET, CTRL_CPU_RESET and CTRL_PWRON_RESET to 1 - catch {mmw 0x40000018 0x7 0x0} - debug_level $lvl + bl602_sw_reset_hbn_wait } diff --git a/tcl/target/bl702l.cfg b/tcl/target/bl702l.cfg new file mode 100644 index 0000000..467dd8c --- /dev/null +++ b/tcl/target/bl702l.cfg @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Bouffalo Labs BL702L and BL704L target +# +# https://en.bouffalolab.com/product/?type=detail&id=26 +# +# Default JTAG pins: (if not changed by eFuse configuration) +# TMS - GPIO0 +# TDI - GPIO1 +# TCK - GPIO2 +# TDO - GPIO7 +# + +if { [info exists CHIPNAME] } { + set BL602_CHIPNAME $CHIPNAME +} else { + set BL602_CHIPNAME bl702l +} + +set CPUTAPID 0x20000e05 + +# For work-area we use beginning of OCRAM, since BL702L have only ITCM, which can be taken +# by L1 cache and XIP during runtime. +set WORKAREAADDR 0x42020000 +set WORKAREASIZE 0x10000 + +source [find target/bl602_common.cfg] + +# JTAG reset is broken. Read comment of bl602_sw_reset function for more information +# On BL702L, we are forcing boot into ISP mode, so chip stays in BootROM until JTAG re-attach +$_TARGETNAME configure -event reset-assert { + halt + + # Restore clocks to defaults + bl602_restore_clock_defaults + + # In HBN_RSV2, set HBN_RELEASE_CORE to HBN_RELEASE_CORE_FLAG (4) + # and HBN_USER_BOOT_SEL to 1 (ISP) + mww 0x4000f108 0x44000000 + + # Perform software reset + bl602_sw_reset + + # Reset HBN_RSV2 so BootROM will not force ISP mode again + mww 0x4000f108 0x00000000 +} diff --git a/tcl/target/ngultra.cfg b/tcl/target/ngultra.cfg index 956fdbb..9f9814f 100644 --- a/tcl/target/ngultra.cfg +++ b/tcl/target/ngultra.cfg @@ -36,12 +36,11 @@ dap create $_CHIPNAME.coresight.dap -chain-position $_CHIPNAME.coresight.cpu for { set _core 0 } { $_core < $_cores } { incr _core } { cti create cti.$_core -dap $_CHIPNAME.coresight.dap -ap-num 0 \ -baseaddr [lindex $CTIBASE $_core] -# Cores are armv8-r but works with aarch64 (since armv8-r not directly supported by openocd yet). if { $_core == 0} { - target create core.$_core aarch64 -dap $_CHIPNAME.coresight.dap \ + target create core.$_core armv8r -dap $_CHIPNAME.coresight.dap \ -ap-num 0 -dbgbase [lindex $DBGBASE $_core] -cti cti.$_core } else { - target create core.$_core aarch64 -dap $_CHIPNAME.coresight.dap \ + target create core.$_core armv8r -dap $_CHIPNAME.coresight.dap \ -ap-num 0 -dbgbase [lindex $DBGBASE $_core] -cti cti.$_core -defer-examine } } diff --git a/tcl/target/nordic/nrf54l.cfg b/tcl/target/nordic/nrf54l.cfg index 70ead13..3e14055 100644 --- a/tcl/target/nordic/nrf54l.cfg +++ b/tcl/target/nordic/nrf54l.cfg @@ -27,18 +27,35 @@ if { [info exists CPUTAPID] } { set _CPUTAPID 0x6ba02477 } +# Multidrop instance ID should be configurable by FW in TAD TINSTANCE register. +# Writes to the register are ignored due to a silicon erratum. +if { [info exists SWD_INSTANCE_ID] } { + set _SWD_INSTANCE_ID $SWD_INSTANCE_ID +} else { + set _SWD_INSTANCE_ID 0 +} + transport select swd swd newdap $_CHIPNAME cpu -expected-id $_CPUTAPID -dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +if { [info exists SWD_MULTIDROP] } { + dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu -dp-id 0x001c0289 -instance-id $_SWD_INSTANCE_ID +} else { + dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu +} set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap -ap-num 0 $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -# Create target for the control access port (CTRL-AP). -target create $_CHIPNAME.ctrl mem_ap -dap $_CHIPNAME.dap -ap-num 1 +# Create target for the AUX access port (AUX-AP). +target create $_CHIPNAME.aux mem_ap -dap $_CHIPNAME.dap -ap-num 1 + +# AUX-AP is accessible only if CSW Prot[0] bit (Data Access) is set +$_CHIPNAME.dap apsel 1 +$_CHIPNAME.dap apcsw 0x01000000 0x01000000 adapter speed 1000 diff --git a/tcl/target/renesas_rcar_gen3.cfg b/tcl/target/renesas_rcar_gen3.cfg index 73b3003..f6bc5e4 100644 --- a/tcl/target/renesas_rcar_gen3.cfg +++ b/tcl/target/renesas_rcar_gen3.cfg @@ -90,6 +90,18 @@ switch $_soc { set _num_cr52 1 set _boot_core CA76 } + V4H { + set _CHIPNAME r8a779g0 + set _num_ca76 4 + set _num_cr52 3 + set _boot_core CR52 + } + V4M { + set _CHIPNAME r8a779h0 + set _num_ca76 4 + set _num_cr52 3 + set _boot_core CR52 + } default { error "'$_soc' is invalid!" } @@ -126,8 +138,8 @@ set CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000} set CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000} set CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000} set CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000} -set CR52_DBGBASE 0x80c10000 -set CR52_CTIBASE 0x80c20000 +set CR52_DBGBASE {0x80C10000 0x80D10000 0x80E10000} +set CR52_CTIBASE {0x80C20000 0x80D20000 0x80E20000} set CR7_DBGBASE 0x80910000 set CR7_CTIBASE 0x80918000 @@ -159,24 +171,27 @@ proc setup_a5x {core_name dbgbase ctibase num boot} { proc setup_crx {core_name dbgbase ctibase num boot} { global _CHIPNAME global _DAPNAME + global smp_targets global _targets for { set _core 0 } { $_core < $num } { incr _core } { - set _TARGETNAME $_CHIPNAME.$core_name + set _TARGETNAME $_CHIPNAME.$core_name.$_core set _CTINAME $_TARGETNAME.cti - cti create $_CTINAME -dap $_DAPNAME -ap-num 1 -baseaddr $ctibase + cti create $_CTINAME -dap $_DAPNAME -ap-num 1 -baseaddr [lindex $ctibase $_core] if { $core_name == "r52" } { set _command "target create $_TARGETNAME armv8r -dap $_DAPNAME \ - -ap-num 1 -dbgbase $dbgbase -cti $_CTINAME" + -ap-num 1 -dbgbase [lindex $dbgbase $_core] -cti $_CTINAME" } else { set _command "target create $_TARGETNAME cortex_r4 -dap $_DAPNAME \ - -ap-num 1 -dbgbase $dbgbase" + -ap-num 1 -dbgbase [lindex $dbgbase $_core]" } - if { $boot == 1 } { + if { $_core == 0 && $boot == 1 } { set _targets "$_TARGETNAME" } else { set _command "$_command -defer-examine" } + set smp_targets "$smp_targets $_TARGETNAME" eval $_command + $_TARGETNAME configure -event examine-end { halt } } } diff --git a/tcl/target/ti_k3.cfg b/tcl/target/ti_k3.cfg index 2ae0f75..0dee74e 100644 --- a/tcl/target/ti_k3.cfg +++ b/tcl/target/ti_k3.cfg @@ -4,8 +4,12 @@ # Texas Instruments K3 devices: # * AM243: https://www.ti.com/lit/pdf/spruim2 # Has 4 R5 Cores, M4F and an M3 +# * AM261: https://www.ti.com/lit/pdf/sprujb6 +# Has 2 R5 Cores and an M4F # * AM263: https://www.ti.com/lit/pdf/spruj17 # Has 4 R5 Cores and an M3 +# * AM263P: https://www.ti.com/lit/pdf/spruj55 +# Has 4 R5 Cores and an M4F # * AM273: https://www.ti.com/lit/pdf/spruiu0 # Has 2 R5 Cores and an M3 # * AM625: https://www.ti.com/lit/pdf/spruiv7a @@ -14,6 +18,8 @@ # Has 4 ARMV8 Cores and 2 R5 Cores # * AM62P: https://www.ti.com/lit/pdf/spruj83 # Has 4 ARMV8 Cores and 2 R5 Cores +# * AM62L: https://www.ti.com/lit/pdf/sprujb4 +# Has 2 ARMv8 Cores only # * AM642: https://www.ti.com/lit/pdf/spruim2 # Has 2 ARMV8 Cores and 4 R5 Cores, M4F and an M3 # * AM654x: https://www.ti.com/lit/pdf/spruid7 @@ -77,8 +83,16 @@ set _gp_mcu_ap_unlock_offsets {0xf0 0x60} # Generic mem-ap port number set _mem_ap_num 2 +# Generic AP_SEL PWR Register number +set _power_ap_num 3 + +# Generic SPREC RESET BANK and Field number +set _powerap_sprec_reset 0xf0 + # Set configuration overrides for each SOC switch $_soc { + am261 - + am263p - am263 { set _K3_DAP_TAPID 0x2bb7d02f @@ -94,6 +108,16 @@ switch $_soc { set R5_DBGBASE {0x90030000 0x90032000 0x90050000 0x90052000} set R5_CTIBASE {0x90038000 0x90039000 0x90058000 0x90059000} set _r5_ap_num 5 + + set _power_ap_num 7 + + if { "$_soc" == "am263p" } { + set _K3_DAP_TAPID 0x1bb9502f + } + if { "$_soc" == "am261" } { + set _K3_DAP_TAPID 0x1bba602f + set _r5_cores 2 + } } am273 { set _K3_DAP_TAPID 0x1bb6a02f @@ -233,6 +257,18 @@ switch $_soc { set R5_CTIBASE {0x9d418000 0x9d518000 0x9d818000} } } + am62l { + set _K3_DAP_TAPID 0x0bba702f + + # AM62Lx has 1 cluster of 2 A53 cores. + set _armv8_cpu_name a53 + set _armv8_cores 2 + set ARMV8_DBGBASE {0x90010000 0x90110000} + set ARMV8_CTIBASE {0x90020000 0x90120000} + + # Has no supporting microcontrollers + set _r5_cores 0 + } j721e { set _K3_DAP_TAPID 0x0bb6402f # J721E has 1 cluster of 2 A72 cores. @@ -499,3 +535,10 @@ if { 0 == [string compare [adapter name] dmem ] } { # AXI AP access port for SoC address map target create $_CHIPNAME.axi_ap mem_ap -dap $_CHIPNAME.dap -ap-num $_mem_ap_num } + +# Reset system using (Debug Reset) SPREC Register,SYSTEMRESET bit field via apreg +proc dbg_sys_reset {} { + $::_CHIPNAME.dap apreg $::_power_ap_num $::_powerap_sprec_reset 0x1 +} + +add_help_text dbg_sys_reset "Debugger initiated system reset attempt via Power-AP" diff --git a/tcl/target/ti_mspm0.cfg b/tcl/target/ti_mspm0.cfg new file mode 100644 index 0000000..4e9b89c --- /dev/null +++ b/tcl/target/ti_mspm0.cfg @@ -0,0 +1,199 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2023-2025 Texas Instruments Incorporated - https://www.ti.com/ +# +# Texas Instruments MSPM0L/G - ARM Cortex-M0 @ 32MHz +# https://www.ti.com/microcontrollers-mcus-processors/arm-based-microcontrollers/arm-cortex-m0-mcus/overview.html +# + +source [find bitsbytes.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + # Meant to work with MSPM0L and MSPM0G class of devices. + set _CHIPNAME mspm0x +} + +if { [info exists CPUTAPID] } { + set _DAP_TAPID $CPUTAPID +} else { + set _DAP_TAPID 0x4ba00477 +} + +if { [info exists DAP_SWD_ID] } { + set _DAP_SWD_ID $DAP_SWD_ID +} else { + set _DAP_SWD_ID 0x2ba01477 +} + +source [find target/swj-dp.tcl] + +# MSPM0 only supports swd, so set it here and save a line for custom boards +transport select swd + +set _DAP_ID $_DAP_SWD_ID + +swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_ID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap + +if { [info exists WORKAREABASE] } { + set _WORKAREABASE $WORKAREABASE +} else { + set _WORKAREABASE 0x20000000 +} +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + # Smallest SRAM size is 1K SRAM. + set _WORKAREASIZE 0x400 +} + +# +# MSPM0 Debug SubSystem Mailbox (DSSM) Communication helpers +# + +proc _mspm0_wait_for_dssm_response {command} { + # Wait for SECAP::RCR rx_valid to be set + set timeout 1000 + while { [expr { [$::_CHIPNAME.dap apreg 2 0xc] & 0x1}] != 0x1 } { + sleep 1 + set timeout [expr {$timeout - 1}] + if { $timeout == 0 } { + set rcr [$::_CHIPNAME.dap apreg 2 0xc] + return -code error [format "MSPM0 SECAP RCR=0x%08x timeout rx_valid" $rcr] + } + } + + # Read SECAP::RXD to clear the RX_VALID bit + set rxd [$::_CHIPNAME.dap apreg 2 0x8] + # Read SECAP::RCR + set rcr [$::_CHIPNAME.dap apreg 2 0xc] + + # Check if we got successful response. This is denoted as: + # 8 LSBits of $command should matchup with SECAP::RCR + # and + # SECAP::RXD should be 0x10003 + if { ([expr { $command & 0xff}] == $rcr) && ($rxd == 0x10003) } { + return 0 + } + + # Provide some debug log for users to report back if CMD fails. + return -code error [format "MSPM0 SECAP CMD FAIL! RXD: 0x%08X RCR: 0x%08X" $rxd $rcr] +} + +proc _mspm0_dssm_command {command} { + # SECAP::TCR = command + $::_CHIPNAME.dap apreg 2 0x4 $command + # SECAP::TDR = 0x0 + $::_CHIPNAME.dap apreg 2 0x0 0x0 + # Read SECAP::RCR and RXD to clear up any prev pending reads + set rxd [$::_CHIPNAME.dap apreg 2 0x8] + set rcr [$::_CHIPNAME.dap apreg 2 0xc] + # Make sure everything is synced + sleep 1000 + # Trigger nRST + mspm0_board_reset + + # Wait for ROM to do it's magic and respond back + set res [_mspm0_wait_for_dssm_response $command] + if { $res } { + return $res + } + # Paranoid.. make sure ROM does what it is meant to do + # RX valid should have been cleared after the operation is + # complete + sleep 1000 + + # Trigger nRST to get back to sane system + mspm0_board_reset + sleep 1000 + + return 0 +} + +# NOTE: Password authentication scheme is NOT supported atm. +# mspm0_factory_reset: Factory reset the board +proc mspm0_factory_reset {} { + set res [_mspm0_dssm_command 0x020a] + if { $res } { + echo "Factory Reset failed!" + } else { + echo "Factory reset success! Halting processor" + # We need to halt the processor else the WDT fires! + halt + } + return $res +} + +add_help_text mspm0_factory_reset "Force Factory reset to recover 'bricked' board" + +# NOTE: Password authentication scheme is NOT supported atm. +# mspm0_mass_erase: Mass erase flash +proc mspm0_mass_erase {} { + set res [_mspm0_dssm_command 0x020c] + if { $res } { + echo "Mass Erase failed!" + } else { + echo "Mass Erase success! Halting Processor" + # We need to halt the processor else the WDT fires! + halt + } + return $res +} + +add_help_text mspm0_mass_erase "Mass erase flash" + +# mspm0_start_bootloader: Ask explicitly for bootloader startup +proc mspm0_start_bootloader {} { + set res [_mspm0_dssm_command 0x0108] + if { $res } { + echo "Start BL failed!" + } + return $res +} + +add_help_text mspm0_start_bootloader "Ask explicitly for bootloader startup" + +# MSPM0 requires board level NRST reset to be toggled for +# Factory reset operations to function. +# However this cannot be the default configuration as this +# prevents reset init reset halt to function properly +# since the Debug Subsystem (debugss) logic or coresight +# seems impacted by nRST. +# This can be overridden in board file as required. +# +# mspm0_board_reset: Board level reset +proc mspm0_board_reset {} { + set user_reset_config [reset_config] + reset_config srst_only + set errno [catch {reset}] + eval reset_config $user_reset_config + if {$errno} {error} +} + +add_help_text mspm0_board_reset "Request a board level reset" + +# If the flash is empty or the device is already in low-power state, then +# debug access is not available. to handle this, explicitly control power ap +# to provide access. Refer to Technical Reference Manual for further info. +proc _mspm0_enable_low_power_mode { } { + # PWR_AP::DPREC <= FRCACT(3)=1, RST_CTL(14:16)=1, IHIB_SLP(20)=1 + $::_CHIPNAME.dap apreg 4 0x00 0x104008 + # PWR_AP::SPREC <= SYSRST=1 + $::_CHIPNAME.dap apreg 4 0xF0 0x01 + # PWR_AP::DPREC <= FRCACT(3)=1, IHIB_SLP(20)=1 + $::_CHIPNAME.dap apreg 4 0x00 0x100008 +} + +$_TARGETNAME configure -event examine-start { _mspm0_enable_low_power_mode } +$_TARGETNAME configure -work-area-phys $_WORKAREABASE -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME.main mspm0 0 0 0 0 $_TARGETNAME +flash bank $_FLASHNAME.nonmain mspm0 0x41c00000 0 0 0 $_TARGETNAME +flash bank $_FLASHNAME.data mspm0 0x41d00000 0 0 0 $_TARGETNAME + +cortex_m reset_config sysresetreq |