From: <ge...@op...> - 2019-02-10 23:17:24
|
This is an automated email from Gerrit. Antonio Borneo (bor...@gm...) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4906 -- gerrit commit cc4b83b1b9f71dce495d060ca4e1b66b6cfc87d1 Author: Antonio Borneo <bor...@gm...> Date: Sun Feb 10 23:36:49 2019 +0100 tcl: improve handling of "reset halt" on multi-core devices The current implementation of proc ocd_process_reset_inner{} requires that every target get halted as result of a "reset halt" or a "reset init" command. If one target cannot halt, the procedure triggers an error and terminates without checking the other targets. If the command was "reset init" the "init" part is not executed anymore, even for those targets that were halted successfully. This is an issue in multi-core SMP Cortex-A devices where, typically, only one core is running after reset; all the other cores are on-hold, either kept in reset or without clock; they would be enabled later by the SW running on the first core. Fix the issue above by printing a message when the target is not halted, instead of issuing an error. Also, the current code waits one second for each target when is checking for the target to get halted. In case of multi-core, the cumulative delay of one second per core is unacceptable. Fix the second issue by computing the deadline as one second from the beginning of the test, then requiring all the targets to halt before the common deadline. This part of code get simplified by the peculiar implementation of arp_waitstate that, while accepting null or negative timeouts, will always check the target's status at least once; there is no need to check if the computed timeout value gets negative or null. To test/validate this commit without a multi-core device, you can use a single core Cortex-M board with a non-HLA adapter: - modify the file src/target/mem_ap.c so mem_ap_deassert_reset() does always set target->state as TARGET_RUNNING. This will make the mem_ap target unable to halt during a "reset halt" - add in the configuration file of Cortex-M board several lines: target create ap0 mem_ap -dap $_CHIPNAME.dap -ap-num 0 target create ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 0 ... With the above modifications run "reset halt". The targets apN will never halt and the you can verify the cumulative delay of one second per target. Change-Id: I3ad0540165f0388b24df2c60c4f445288110e46d Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/target/startup.tcl b/src/target/startup.tcl index cf844e1..d44d5c4 100644 --- a/src/target/startup.tcl +++ b/src/target/startup.tcl @@ -106,6 +106,10 @@ proc ocd_process_reset_inner { MODE } { # assert/deassert) to happen. Ideally it takes effect without # first executing any instructions. if { $halt } { + # Wait up to 1 second for targets to halt. + # Why 1sec? Cause the JTAG tap reset signal might be hooked to a slow + # resistor/capacitor circuit - and it might take a while to charge + set expire_time_ms [expr [clock milliseconds] + 1000] foreach t $targets { if {[using_jtag] && ![jtag tapisenabled [$t cget -chain-position]]} { continue @@ -117,19 +121,17 @@ proc ocd_process_reset_inner { MODE } { continue } - # Wait upto 1 second for target to halt. Why 1sec? Cause - # the JTAG tap reset signal might be hooked to a slow - # resistor/capacitor circuit - and it might take a while - # to charge + # Timeout for arp_waitstate. Negative value is ok, no check required + set timeout_ms [expr $expire_time_ms - [clock milliseconds]] # Catch, but ignore any errors. - catch { $t arp_waitstate halted 1000 } + catch { $t arp_waitstate halted $timeout_ms } # Did we succeed? set s [$t curstate] if { 0 != [string compare $s "halted" ] } { - return -code error [format "TARGET: %s - Not halted" $t] + echo [format "TARGET: %s - Not halted" $t] } } } -- |