From: David B. <dbr...@us...> - 2009-11-28 03:54:44
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 5782999f6030acb560a3b02da10354eb099c45a4 (commit) via ddce517e3a2144e27a26090aef7ef1a7f2270af1 (commit) via e0cb27df6bc595650ca6ce205803d3aa3218e262 (commit) via 4e56a2303b3f68bb647d8bb640a830f7f21ea231 (commit) via 4d2750e571b6a3f700cd95542a4bb5c7949e476c (commit) from 77aa7ca8d65ac5dc7b46ad9ef79e3f6aed9b4d0e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5782999f6030acb560a3b02da10354eb099c45a4 Author: David Brownell <dbr...@us...> Date: Fri Nov 27 18:53:43 2009 -0800 NEWS: mention new reset-assert event Signed-off-by: David Brownell <dbr...@us...> diff --git a/NEWS b/NEWS index c5811bc..b7eb0f0 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ JTAG Layer: Boundary Scan: Target Layer: + General + - new "reset-assert" event, for systems without SRST ARM - renamed "armv4_5" command prefix as "arm" - recognize TrustZone "Secure Monitor" mode @@ -22,6 +24,7 @@ Target Layer: Cortex-A8 - support "arm regs" command - can access all core modes and registers + - supports "reset-assert" event (used on OMAP3530) Cortex-M3 - Exposed DWT registers like cycle counter commit ddce517e3a2144e27a26090aef7ef1a7f2270af1 Author: David Brownell <dbr...@us...> Date: Fri Nov 27 18:50:31 2009 -0800 omap3530.cfg: use new "reset-assert" event Replaces previous "reset-assert-pre" workaround. Signed-off-by: David Brownell <dbr...@us...> diff --git a/tcl/target/omap3530.cfg b/tcl/target/omap3530.cfg index 0a83423..74edd72 100644 --- a/tcl/target/omap3530.cfg +++ b/tcl/target/omap3530.cfg @@ -65,10 +65,10 @@ proc omap3_dbginit {target} { jtag_rclk 1000 $_TARGETNAME configure -event "reset-start" { jtag_rclk 1000 } -# REVISIT This assumes that SRST is unavailable, so we must assert reset +# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset # ourselves using PRM_RSTCTRL. RST_GS (2) is a warm reset, like ICEpick # would issue. RST_DPLL3 (4) is a cold reset. set PRM_RSTCTRL 0x48307250 -$_TARGETNAME configure -event reset-assert-pre "$_TARGETNAME mww $PRM_RSTCTRL 2" +$_TARGETNAME configure -event reset-assert "$_TARGETNAME mww $PRM_RSTCTRL 2" $_TARGETNAME configure -event reset-assert-post "omap3_dbginit $_TARGETNAME" commit e0cb27df6bc595650ca6ce205803d3aa3218e262 Author: David Brownell <dbr...@us...> Date: Fri Nov 27 18:50:26 2009 -0800 Cortex-A8: support "reset-assert" event Use the new "reset-assert" event; else SRST; else fail. Tested on an OMAP3, using the event. NOTE: still doesn't handle "reset halt". For some reason neither VCR nor PRCR seemed effective; they held the value that was written, but VCR didn't trigger debug entry when the reset vector fired (maybe the vector needs configuring?) and PRCR refused to hold the chip in reset until deassert() could force the core into debug state. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c index b85481a..8402081 100644 --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -1246,6 +1246,21 @@ static int cortex_a8_assert_reset(struct target *target) LOG_DEBUG(" "); + /* FIXME when halt is requested, make it work somehow... */ + + /* Issue some kind of warm reset. */ + if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) { + target_handle_event(target, TARGET_EVENT_RESET_ASSERT); + } else if (jtag_get_reset_config() & RESET_HAS_SRST) { + /* REVISIT handle "pulls" cases, if there's + * hardware that needs them to work. + */ + jtag_add_reset(0, 1); + } else { + LOG_ERROR("%s: how to reset?", target_name(target)); + return ERROR_FAIL; + } + /* registers are now invalid */ register_cache_invalidate(armv7a->armv4_5_common.core_cache); @@ -1256,14 +1271,22 @@ static int cortex_a8_assert_reset(struct target *target) static int cortex_a8_deassert_reset(struct target *target) { + int retval; LOG_DEBUG(" "); - if (target->reset_halt) - { - int retval; - if ((retval = target_halt(target)) != ERROR_OK) - return retval; + /* be certain SRST is off */ + jtag_add_reset(0, 0); + + retval = cortex_a8_poll(target); + + if (target->reset_halt) { + if (target->state != TARGET_HALTED) { + LOG_WARNING("%s: ran after reset and before halt ...", + target_name(target)); + if ((retval = target_halt(target)) != ERROR_OK) + return retval; + } } return ERROR_OK; commit 4e56a2303b3f68bb647d8bb640a830f7f21ea231 Author: David Brownell <dbr...@us...> Date: Fri Nov 27 18:50:20 2009 -0800 target: groundwork for "reset-assert" event This defines a "reset-assert" event and a supporting utility routine, and documents both how targets should implement it and how config scripts should use it. Core-specific updates are needed to make this work. Signed-off-by: David Brownell <dbr...@us...> diff --git a/doc/openocd.texi b/doc/openocd.texi index e94c9d0..b32ed21 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -1411,6 +1411,20 @@ chip can be tweaked by the board. Some chips have specific ways the TRST and SRST signals are managed. In the unusual case that these are @emph{chip specific} and can never be changed by board wiring, they could go here. +For example, some chips can't support JTAG debugging without +both signals. + +Provide a @code{reset-assert} event handler if you can. +Such a handler uses JTAG operations to reset the target, +letting this target config be used in systems which don't +provide the optional SRST signal, or on systems where you +don't want to reset all targets at once. +Such a handler might write to chip registers to force a reset, +use a JRC to do that (preferable -- the target may be wedged!), +or force a watchdog timer to trigger. +(For Cortex-M3 targets, this is not necessary. The target +driver knows how to use trigger an NVIC reset when SRST is +not available.) Some chips need special attention during reset handling if they're going to be used with JTAG. @@ -1418,6 +1432,8 @@ An example might be needing to send some commands right after the target's TAP has been reset, providing a @code{reset-deassert-post} event handler that writes a chip register to report that JTAG debugging is being done. +Another would be reconfiguring the watchdog so that it stops +counting while the core is halted in the debugger. JTAG clocking constraints often change during reset, and in some cases target config files (rather than board config files) @@ -2401,6 +2417,12 @@ There are also @emph{event handlers} associated with TAPs or Targets. Those handlers are Tcl procedures you can provide, which are invoked at particular points in the reset sequence. +@emph{When SRST is not an option} you must set +up a @code{reset-assert} event handler for your target. +For example, some JTAG adapters don't include the SRST signal; +and some boards have multiple targets, and you won't always +want to reset everything at once. + After configuring those mechanisms, you might still find your board doesn't start up or reset correctly. For example, maybe it needs a slightly different sequence @@ -3390,9 +3412,14 @@ For example: @itemize @bullet @item What should happen when GDB connects? Should your target reset? @item When GDB tries to flash the target, do you need to enable the flash via a special command? +@item Is using SRST appropriate (and possible) on your system? +Or instead of that, do you need to issue JTAG commands to trigger reset? +SRST usually resets everything on the scan chain, which can be inappropriate. @item During reset, do you need to write to certain memory locations to set up system clocks or to reconfigure the SDRAM? +How about configuring the watchdog timer, or other peripherals, +to stop running while you hold the core stopped for debugging? @end itemize All of the above items can be addressed by target event handlers. @@ -3457,16 +3484,28 @@ The following target events are defined: @item @b{reset-assert-pre} @* Issued as part of @command{reset} processing after @command{reset_init} was triggered -but before SRST alone is re-asserted on the tap. +but before either SRST alone is re-asserted on the scan chain, +or @code{reset-assert} is triggered. +@item @b{reset-assert} +@* Issued as part of @command{reset} processing +after @command{reset-assert-pre} was triggered. +When such a handler is present, cores which support this event will use +it instead of asserting SRST. +This support is essential for debugging with JTAG interfaces which +don't include an SRST line (JTAG doesn't require SRST), and for +selective reset on scan chains that have multiple targets. @item @b{reset-assert-post} @* Issued as part of @command{reset} processing -when SRST is asserted on the tap. +after @code{reset-assert} has been triggered. +or the target asserted SRST on the entire scan chain. @item @b{reset-deassert-pre} @* Issued as part of @command{reset} processing -when SRST is about to be released on the tap. +after @code{reset-assert-post} has been triggered. @item @b{reset-deassert-post} @* Issued as part of @command{reset} processing -when SRST has been released on the tap. +after @code{reset-deassert-pre} has been triggered +and (if the target is using it) after SRST has been +released on the scan chain. @item @b{reset-end} @* Issued as the final step in @command{reset} processing. @ignore diff --git a/src/target/target.c b/src/target/target.c index 3de9f2c..a2bd886 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -147,6 +147,7 @@ static const Jim_Nvp nvp_target_event[] = { { .value = TARGET_EVENT_RESET_START, .name = "reset-start" }, { .value = TARGET_EVENT_RESET_ASSERT_PRE, .name = "reset-assert-pre" }, + { .value = TARGET_EVENT_RESET_ASSERT, .name = "reset-assert" }, { .value = TARGET_EVENT_RESET_ASSERT_POST, .name = "reset-assert-post" }, { .value = TARGET_EVENT_RESET_DEASSERT_PRE, .name = "reset-deassert-pre" }, { .value = TARGET_EVENT_RESET_DEASSERT_POST, .name = "reset-deassert-post" }, @@ -154,8 +155,8 @@ static const Jim_Nvp nvp_target_event[] = { { .value = TARGET_EVENT_RESET_HALT_POST, .name = "reset-halt-post" }, { .value = TARGET_EVENT_RESET_WAIT_PRE, .name = "reset-wait-pre" }, { .value = TARGET_EVENT_RESET_WAIT_POST, .name = "reset-wait-post" }, - { .value = TARGET_EVENT_RESET_INIT , .name = "reset-init" }, - { .value = TARGET_EVENT_RESET_END, .name = "reset-end" }, + { .value = TARGET_EVENT_RESET_INIT, .name = "reset-init" }, + { .value = TARGET_EVENT_RESET_END, .name = "reset-end" }, { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" }, { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" }, @@ -3523,6 +3524,20 @@ void target_handle_event(struct target *target, enum target_event e) } } +/** + * Returns true only if the target has a handler for the specified event. + */ +bool target_has_event_action(struct target *target, enum target_event event) +{ + struct target_event_action *teap; + + for (teap = target->event_action; teap != NULL; teap = teap->next) { + if (teap->event == event) + return true; + } + return false; +} + enum target_cfg_param { TCFG_TYPE, TCFG_EVENT, diff --git a/src/target/target.h b/src/target/target.h index 15003c6..55e9088 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -196,6 +196,7 @@ enum target_event TARGET_EVENT_RESET_START, TARGET_EVENT_RESET_ASSERT_PRE, + TARGET_EVENT_RESET_ASSERT, /* C code uses this instead of SRST */ TARGET_EVENT_RESET_ASSERT_POST, TARGET_EVENT_RESET_DEASSERT_PRE, TARGET_EVENT_RESET_DEASSERT_POST, @@ -226,7 +227,9 @@ struct target_event_action { struct Jim_Obj *body; int has_percent; struct target_event_action *next; - }; +}; + +bool target_has_event_action(struct target *target, enum target_event event); struct target_event_callback { commit 4d2750e571b6a3f700cd95542a4bb5c7949e476c Author: David Brownell <dbr...@us...> Date: Fri Nov 27 18:40:37 2009 -0800 ARM11: write_memory() avoids increment check When writing to a chip's "reset yourself" register, the ARM11 code was reporting a spurious failure. Just don't bother checking for correctly incremented pointers given single-unit writes ... it's a bit faster that way too. (Reads should likely do the same thing. For that matter, such checks are usually just a waste...) Shrink an overlong parameter name, and associated lines'o'code. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm11.c b/src/target/arm11.c index 7c6d39c..daba3b8 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -989,13 +989,14 @@ static int arm11_read_memory(struct target *target, uint32_t address, uint32_t s } /* -* arm11_config_memrw_no_increment - in the future we may want to be able +* no_increment - in the future we may want to be able * to read/write a range of data to a "port". a "port" is an action on * read memory address for some peripheral. */ static int arm11_write_memory_inner(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer, - bool arm11_config_memrw_no_increment) + uint32_t address, uint32_t size, + uint32_t count, uint8_t *buffer, + bool no_increment) { int retval; @@ -1043,7 +1044,9 @@ static int arm11_write_memory_inner(struct target *target, /* strb r1, [r0], #1 */ /* strb r1, [r0] */ retval = arm11_run_instr_no_data1(arm11, - !arm11_config_memrw_no_increment ? 0xe4c01001 : 0xe5c01000); + !no_increment + ? 0xe4c01001 + : 0xe5c01000); if (retval != ERROR_OK) return retval; } @@ -1068,7 +1071,9 @@ static int arm11_write_memory_inner(struct target *target, /* strh r1, [r0], #2 */ /* strh r1, [r0] */ retval = arm11_run_instr_no_data1(arm11, - !arm11_config_memrw_no_increment ? 0xe0c010b2 : 0xe1c010b0); + !no_increment + ? 0xe0c010b2 + : 0xe1c010b0); if (retval != ERROR_OK) return retval; } @@ -1077,7 +1082,7 @@ static int arm11_write_memory_inner(struct target *target, } case 4: { - uint32_t instr = !arm11_config_memrw_no_increment ? 0xeca05e01 : 0xed805e00; + uint32_t instr = !no_increment ? 0xeca05e01 : 0xed805e00; /** \todo TODO: buffer cast to uint32_t* causes alignment warnings */ uint32_t *words = (uint32_t*)buffer; @@ -1104,7 +1109,7 @@ static int arm11_write_memory_inner(struct target *target, } /* r0 verification */ - if (!arm11_config_memrw_no_increment) + if (!no_increment) { uint32_t r0; @@ -1132,9 +1137,14 @@ static int arm11_write_memory_inner(struct target *target, } static int arm11_write_memory(struct target *target, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t address, uint32_t size, + uint32_t count, uint8_t *buffer) { - return arm11_write_memory_inner(target, address, size, count, buffer, false); + /* pointer increment matters only for multi-unit writes ... + * not e.g. to a "reset the chip" controller. + */ + return arm11_write_memory_inner(target, address, size, + count, buffer, count == 1); } /* write target memory in multiples of 4 byte, optimized for writing large quantities of data */ ----------------------------------------------------------------------- Summary of changes: NEWS | 3 +++ doc/openocd.texi | 47 +++++++++++++++++++++++++++++++++++++++++++---- src/target/arm11.c | 28 +++++++++++++++++++--------- src/target/cortex_a8.c | 33 ++++++++++++++++++++++++++++----- src/target/target.c | 19 +++++++++++++++++-- src/target/target.h | 5 ++++- tcl/target/omap3530.cfg | 4 ++-- 7 files changed, 116 insertions(+), 23 deletions(-) hooks/post-receive -- Main OpenOCD repository |