-# Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal
-# HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3
-# makes the data access cacheable. This allows reading and writing data in the
-# CPU cache from the debugger, which is far more useful than going straight to
-# RAM when operating on typical variables, and is generally no worse when
-# operating on special memory locations.
-$_CHIPNAME.dap apcsw 0x08000000 0x08000000
+# like mrw, but with target selection
+proc stm32h7x_mrw {used_target reg} {
+ set value ""
+ $used_target mem2array value 32 $reg 1
+ return $value(0)
+}
+
+# like mmw, but with target selection
+proc stm32h7x_mmw {used_target reg setbits clearbits} {
+ set old [stm32h7x_mrw $used_target $reg]
+ set new [expr ($old & ~$clearbits) | $setbits]
+ $used_target mww $reg $new
+}
+
+# mmw for dbgmcu component registers, it accepts the register offset from dbgmcu base
+# this procedure will use the mem_ap on AP2 whenever possible
+proc stm32h7x_dbgmcu_mmw {reg_offset setbits clearbits} {
+ # use $_CHIPNAME.ap2 if possible, and use the proper dbgmcu base address
+ if {![using_hla]} {
+ # get _CHIPNAME from the current target
+ set _CHIPNAME [regsub ".(cpu|ap)\\d*$" [target current] ""]
+ set used_target $_CHIPNAME.ap2
+ set reg_addr [expr 0xE00E1000 + $reg_offset]
+ } {
+ set used_target [target current]
+ set reg_addr [expr 0x5C001000 + $reg_offset]
+ }
+
+ stm32h7x_mmw $used_target $reg_addr $setbits $clearbits
+}
+
+if {[set $_CHIPNAME.USE_CTI]} {
+ # create CTI instances for both cores
+ cti create $_CHIPNAME.cti0 -dap $_CHIPNAME.dap -ap-num 0 -ctibase 0xE0043000
+ cti create $_CHIPNAME.cti1 -dap $_CHIPNAME.dap -ap-num 3 -ctibase 0xE0043000
+
+ $_CHIPNAME.cpu0 configure -event halted { stm32h7x_cti_prepare_restart_all }
+ $_CHIPNAME.cpu1 configure -event halted { stm32h7x_cti_prepare_restart_all }
+
+ $_CHIPNAME.cpu0 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }
+ $_CHIPNAME.cpu1 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }
+
+ proc stm32h7x_cti_start {} {
+ # get _CHIPNAME from the current target
+ set _CHIPNAME [regsub ".cpu\\d$" [target current] ""]
+
+ # Configure Cores' CTIs to halt each other
+ # TRIGIN0 (DBGTRIGGER) and TRIGOUT0 (EDBGRQ) at CTM_CHANNEL_0
+ $_CHIPNAME.cti0 write INEN0 0x1
+ $_CHIPNAME.cti0 write OUTEN0 0x1
+ $_CHIPNAME.cti1 write INEN0 0x1
+ $_CHIPNAME.cti1 write OUTEN0 0x1
+
+ # enable CTIs
+ $_CHIPNAME.cti0 enable on
+ $_CHIPNAME.cti1 enable on
+ }
+
+ proc stm32h7x_cti_stop {} {
+ # get _CHIPNAME from the current target
+ set _CHIPNAME [regsub ".cpu\\d$" [target current] ""]
+
+ $_CHIPNAME.cti0 enable off
+ $_CHIPNAME.cti1 enable off
+ }
+
+ proc stm32h7x_cti_prepare_restart_all {} {
+ stm32h7x_cti_prepare_restart cti0
+ stm32h7x_cti_prepare_restart cti1
+ }
+
+ proc stm32h7x_cti_prepare_restart {cti} {
+ # get _CHIPNAME from the current target
+ set _CHIPNAME [regsub ".cpu\\d$" [target current] ""]
+
+ # Acknowlodge EDBGRQ at TRIGOUT0
+ $_CHIPNAME.$cti write INACK 0x01
+ $_CHIPNAME.$cti write INACK 0x00
+ }
+}