]> www.infradead.org Git - users/borneoa/openocd-next.git/commitdiff
tcl/target: Add support for TI MSPM0
authorNishanth Menon <nm@ti.com>
Thu, 28 Sep 2023 08:37:03 +0000 (03:37 -0500)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sun, 9 Mar 2025 13:26:26 +0000 (13:26 +0000)
Add basic support for Texas Instruments MSPM0L, C and G family of
Cortex-M0 based micro-controllers.

Change-Id: If2b5b1eca001f74d501ede67ec621c7497548a85
Co-developed-by: Henry Nguyen <h-nguyen8@ti.com>
Signed-off-by: Henry Nguyen <h-nguyen8@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8385
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-by: zapb <dev@zapb.de>
doc/openocd.texi
tcl/target/ti_mspm0.cfg [new file with mode: 0644]

index 68c7a825bdd293a7ac8bb43b14530f671787a6db..386528a9d6bf398583636c29338d9a3a7d155402 100644 (file)
@@ -7438,6 +7438,7 @@ flash bank $_FLASHNAME mspm0 0 0 0 0 $_TARGETNAME
 halt
 flash erase_sector 0 0 last
 flash write_image MAIN.bin 0x0
+mspm0_board_reset
 @end example
 
 @item @b{To erase and program the NONMAIN region:}
@@ -7445,10 +7446,29 @@ flash write_image MAIN.bin 0x0
 halt
 flash erase_sector 1 0 last
 flash write_image NONMAIN.bin 0x41C00000
+mspm0_board_reset
 @end example
 
 @end itemize
 
+@deffn {TCL proc} {mspm0_board_reset}
+Performs an nRST toggle on the device.
+@end deffn
+
+@deffn {TCL proc} {mspm0_mass_erase}
+Sends the mass erase command to the SEC-AP mailbox and then performs
+an nRST toggle. Once the command has been fully processed by the ROM,
+all MAIN memory will be erased. NOTE: This command is not supported
+on MSPM0C* family of devices.
+@end deffn
+
+@deffn {TCL proc} {mspm0_factory_reset}
+Sends the factory reset command to the SEC-AP mailbox and then performs
+an nRST toggle. Once the command has been fully processed by the ROM,
+all MAIN memory will be erased and NONMAIN will be reset to its default
+values.
+@end deffn
+
 @end deffn
 
 @deffn {Flash Driver} {niietcm4}
diff --git a/tcl/target/ti_mspm0.cfg b/tcl/target/ti_mspm0.cfg
new file mode 100644 (file)
index 0000000..4e9b89c
--- /dev/null
@@ -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