This is an automated email from Gerrit. "Ahmed Haoues <[email protected]>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9355
-- gerrit commit 64943999518700af5c82f271a2065b6774a5db0b Author: HAOUES Ahmed <[email protected]> Date: Thu Dec 25 15:44:20 2025 +0100 tcl/target: Add STM32N6x support Add configuration file for STM32N6 Change-Id: Ia59786858724b6be141ec5f40a8d30459fb26dfb Signed-off-by: HAOUES Ahmed <[email protected]> diff --git a/tcl/target/stm32n6x.cfg b/tcl/target/stm32n6x.cfg new file mode 100644 index 0000000000..53d07df36c --- /dev/null +++ b/tcl/target/stm32n6x.cfg @@ -0,0 +1,170 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# script for stm32n6x family +# stm32n6 devices support both JTAG and SWD transports. + +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32n6x +} + +# Work-area is a space in RAM used for flash programming +# By default use 64kB +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x10000 +} + +#jtag scan chain +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + if { [using_jtag] } { + set _CPUTAPID 0x6ba00477 + } { + set _CPUTAPID 0x6ba02477 + } +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +set _TARGETNAME $_CHIPNAME.cpu + +dap create $_CHIPNAME.dap -chain-position $_TARGETNAME + +target create $_CHIPNAME.ap0 mem_ap -endian little -dap $_CHIPNAME.dap -ap-num 0 + +target create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap -ap-num 1 -gdb-max-connections 2 + +# use secure RAM by default +$_TARGETNAME configure -work-area-phys 0x34000000 -work-area-size $_WORKAREASIZE -work-area-backup 1 + +if { ![using_hla] } { + swo create $_CHIPNAME.swo -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE008A000 + tpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0084000 +} + +adapter speed 8000 + +adapter srst delay 100 +if {[using_jtag]} { + jtag_ntrst_delay 100 +} + +if { ![using_hla] } { + # Use SYSRESETREQ to perform a soft reset if SRST is not fitted. + cortex_m reset_config sysresetreq +} + +proc stm32n6x_is_secure {} { + # read Debug Security Control and Status Regsiter (DSCSR) and check CDS (bit 16) + set DSCSR [mrw 0xE000EE08] + return [expr {($DSCSR & (1 << 16)) != 0}] +} + +proc stm32n6x_ahb_ap_non_secure_access {} { + [[target current] cget -dap] apsel 1 + # SPROT=1=Non Secure access, Priv=1 + [[target current] cget -dap] apcsw 0x4B000000 0x4F000000 +} + +proc stm32n6x_ahb_ap_secure_access {} { + [[target current] cget -dap] apsel 1 + # SPROT=0=Secure access, Priv=1 + [[target current] cget -dap] apcsw 0x0B000000 0x4F000000 +} + +# get _CHIPNAME from current target +proc stm32n6x_get_chipname {} { + set t [target current] + set sep [string last "." $t] + if {$sep == -1} { + return $t + } + return [string range $t 0 [expr {$sep - 1}]] +} + +# like mrw, but with target selection +proc stm32n6x_mrw {used_target reg} { + return [$used_target read_memory $reg 32 1] +} + +# like mmw, but with target selection +proc stm32n6x_mmw {used_target reg setbits clearbits} { + set old [stm32n6x_mrw $used_target $reg] + set new [expr {($old & ~$clearbits) | $setbits}] + $used_target mww $reg $new +} + +proc stm32n6x_enter_debug {} { + set _CHIPNAME [stm32n6x_get_chipname] + + # check security status + set secure [stm32n6x_is_secure] + + if {$secure} { + stm32n6x_ahb_ap_secure_access + } else { + stm32n6x_ahb_ap_non_secure_access + } + + # print the secure state only when it changes + global $_CHIPNAME.secure + + if {![info exists $_CHIPNAME.secure] || $secure != [set $_CHIPNAME.secure]} { + # update saved security state + set $_CHIPNAME.secure $secure + set secure_str [expr {$secure ? "Secure" : "Non-Secure"}] + echo "$_CHIPNAME.cpu in $secure_str state" + } + + # use secure workarea only when TrustZone is enabled + set use_secure_workarea 1 + set workarea_addr [$_CHIPNAME.cpu cget -work-area-phys] + + if {$use_secure_workarea} { + set workarea_addr [expr {$workarea_addr | 0x10000000}] + } else { + set workarea_addr [expr {$workarea_addr & ~0x10000000}] + } + + $_CHIPNAME.cpu configure -work-area-phys $workarea_addr + + global $_CHIPNAME.workarea_size + if {![info exists $_CHIPNAME.workarea_size]} { + set $_CHIPNAME.workarea_size [$_CHIPNAME.cpu cget -work-area-size] + } + + set workarea_size [set $_CHIPNAME.workarea_size] + $_CHIPNAME.cpu configure -work-area-size $workarea_size +} + +$_CHIPNAME.ap0 configure -event examine-end { + set _CHIPNAME [stm32n6x_get_chipname] + # Enable Trace Port and DBG Clock (uses more power) + # DBGMCU_CR |= DBGCLK_EN | TRACECLK_EN + stm32n6x_mmw $_CHIPNAME.ap0 0x44001004 0x00300000 0 +} + +$_TARGETNAME configure -event examine-end { + stm32n6x_enter_debug + set _CHIPNAME [stm32n6x_get_chipname] + + # Enable debug during low power modes (uses more power) + # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP + stm32n6x_mmw $_CHIPNAME.ap0 0x44001004 0x00000007 0 + + # Stop watchdog counters during halt + # DBGMCU_APB1LFZ |= DBG_WWDG_STOP + stm32n6x_mmw $_CHIPNAME.ap0 0x44001010 0x00000800 0 + # DBGMCU_APB4FZ |= DBG_IWDG_STOP + stm32n6x_mmw $_CHIPNAME.ap0 0x4400101C 0x00040000 0 +} + +$_TARGETNAME configure -event halted { + stm32n6x_enter_debug +} --
