Add configuration file for STM32N6 Change-Id: Ia59786858724b6be141ec5f40a8d30459fb26dfb Signed-off-by: HAOUES Ahmed <ahmed.haoues@st.com> Reviewed-on: https://review.openocd.org/c/openocd/+/9355 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
168 lines
4.7 KiB
INI
168 lines
4.7 KiB
INI
# 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
|
|
|
|
# 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] } {
|
|
echo "Warn : The selected adapter does not support debugging this device in secure mode"
|
|
} else {
|
|
# 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 Register (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 {} {
|
|
return [regsub {\.[^.]*$} [target current] {}]
|
|
}
|
|
|
|
# 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
|
|
}
|