You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(75) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(70) |
Feb
(20) |
Mar
(52) |
Apr
(149) |
May
(387) |
Jun
(466) |
Jul
(133) |
Aug
(87) |
Sep
(122) |
Oct
(140) |
Nov
(185) |
Dec
(105) |
2010 |
Jan
(85) |
Feb
(45) |
Mar
(75) |
Apr
(17) |
May
(41) |
Jun
(52) |
Jul
(33) |
Aug
(29) |
Sep
(36) |
Oct
(15) |
Nov
(26) |
Dec
(34) |
2011 |
Jan
(26) |
Feb
(25) |
Mar
(26) |
Apr
(29) |
May
(20) |
Jun
(27) |
Jul
(15) |
Aug
(32) |
Sep
(13) |
Oct
(64) |
Nov
(60) |
Dec
(10) |
2012 |
Jan
(64) |
Feb
(63) |
Mar
(39) |
Apr
(43) |
May
(54) |
Jun
(11) |
Jul
(30) |
Aug
(45) |
Sep
(11) |
Oct
(70) |
Nov
(24) |
Dec
(23) |
2013 |
Jan
(17) |
Feb
(8) |
Mar
(35) |
Apr
(40) |
May
(20) |
Jun
(24) |
Jul
(36) |
Aug
(25) |
Sep
(42) |
Oct
(40) |
Nov
(9) |
Dec
(21) |
2014 |
Jan
(29) |
Feb
(24) |
Mar
(60) |
Apr
(22) |
May
(22) |
Jun
(46) |
Jul
(11) |
Aug
(23) |
Sep
(26) |
Oct
(10) |
Nov
(14) |
Dec
(2) |
2015 |
Jan
(28) |
Feb
(47) |
Mar
(33) |
Apr
(58) |
May
(5) |
Jun
(1) |
Jul
|
Aug
(8) |
Sep
(12) |
Oct
(25) |
Nov
(58) |
Dec
(21) |
2016 |
Jan
(12) |
Feb
(40) |
Mar
(2) |
Apr
(1) |
May
(67) |
Jun
(2) |
Jul
(5) |
Aug
(36) |
Sep
|
Oct
(24) |
Nov
(17) |
Dec
(50) |
2017 |
Jan
(14) |
Feb
(16) |
Mar
(2) |
Apr
(35) |
May
(14) |
Jun
(16) |
Jul
(3) |
Aug
(3) |
Sep
|
Oct
(19) |
Nov
|
Dec
(16) |
2018 |
Jan
(55) |
Feb
(11) |
Mar
(34) |
Apr
(14) |
May
(4) |
Jun
(20) |
Jul
(39) |
Aug
(16) |
Sep
(17) |
Oct
(16) |
Nov
(20) |
Dec
(30) |
2019 |
Jan
(29) |
Feb
(24) |
Mar
(37) |
Apr
(26) |
May
(19) |
Jun
(21) |
Jul
(2) |
Aug
(3) |
Sep
(9) |
Oct
(12) |
Nov
(12) |
Dec
(12) |
2020 |
Jan
(47) |
Feb
(36) |
Mar
(54) |
Apr
(44) |
May
(37) |
Jun
(19) |
Jul
(32) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(32) |
Dec
(11) |
2021 |
Jan
(14) |
Feb
(5) |
Mar
(40) |
Apr
(32) |
May
(42) |
Jun
(31) |
Jul
(29) |
Aug
(47) |
Sep
(38) |
Oct
(17) |
Nov
(74) |
Dec
(33) |
2022 |
Jan
(11) |
Feb
(15) |
Mar
(40) |
Apr
(21) |
May
(39) |
Jun
(44) |
Jul
(19) |
Aug
(46) |
Sep
(79) |
Oct
(35) |
Nov
(21) |
Dec
(15) |
2023 |
Jan
(56) |
Feb
(13) |
Mar
(43) |
Apr
(28) |
May
(60) |
Jun
(15) |
Jul
(29) |
Aug
(28) |
Sep
(32) |
Oct
(21) |
Nov
(42) |
Dec
(39) |
2024 |
Jan
(35) |
Feb
(17) |
Mar
(28) |
Apr
(7) |
May
(14) |
Jun
(35) |
Jul
(30) |
Aug
(35) |
Sep
(30) |
Oct
(28) |
Nov
(38) |
Dec
(18) |
2025 |
Jan
(21) |
Feb
(28) |
Mar
(36) |
Apr
(35) |
May
(34) |
Jun
(58) |
Jul
(9) |
Aug
(37) |
Sep
|
Oct
|
Nov
|
Dec
|
From: David B. <dbr...@us...> - 2010-03-06 06:09:23
|
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 c6e323b9838254b338310ec165a5345635c5d177 (commit) via 74113cf72570a20f5f2ff66f721284bd4228aee3 (commit) from d33a81c549743e13633db9e8749f0e7cb0f7324b (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 c6e323b9838254b338310ec165a5345635c5d177 Author: David Brownell <dbr...@us...> Date: Fri Mar 5 21:09:03 2010 -0800 doc: not all debug adapters are "dongles" Talk more about "debug adapters" instead of only "dongles". Not all adapters are discrete widgets; some are integrated onto boards. If we only talk about "dongles" we rule out many valid setups, and help confuse some users (who may be using Dongle-free environments). Also start bringing out the point that JTAG isn't the only transport protocol, even though OpenOCD historically presumes "all is JTAG". (Not all debug adapters are JTAG adapters, or JTAG-only adapters.) Plus a few minor fixes (spelling etc) in the vicinity of those changes, and updates about FT2232H clocking issues (they can go faster than the older chips, and can support adaptive clocking). Signed-off-by: David Brownell <dbr...@us...> diff --git a/doc/manual/server.txt b/doc/manual/server.txt index 5250f7f..f75f1d1 100644 --- a/doc/manual/server.txt +++ b/doc/manual/server.txt @@ -207,7 +207,7 @@ upon it, sometimes that is the only scheme available. As a small group of developers, supporting all the platforms and targets in the debugger will be difficult, as there are enough problem -with the plethora of Dongles, Chips, and different target boards. +with the plethora of Adapters, Chips, and different target boards. Yes, the TCL interface might be suitable, but it has not received much love or attention. Perhaps it will after you read and understand this. @@ -235,7 +235,7 @@ different host-side GDB.. Sure - a <em>man on a mission</em> can make that work. The GUI might be libopenocd + Perl/TK, or maybe an Eclipse Plug-in. That is a development support nightmare for reasons described -above. We have enough support problems as it is with targets, dongles, +above. We have enough support problems as it is with targets, adapters, etc. @section serverdocshttpbg HTTP Server Background @@ -270,8 +270,8 @@ every peripheral register on the target platform. That also is transportable, regardless of the OpenOCD host platform: Linux/X86, Linux/ARM, FreeBSD, Cygwin, MingW, or MacOSX. -You could even port OpenOCD to an Google Android and use it as a -bit-bang dongle JTAG serving web pages. +You could even port OpenOCD to an Android system and use it as a +bit-banging JTAG Adapter serving web pages. @subsection serverdocshtmladv Advanced HTML Pages diff --git a/doc/openocd.texi b/doc/openocd.texi index 507498f..f9f9b68 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -61,13 +61,13 @@ Free Documentation License''. @menu * About:: About OpenOCD * Developers:: OpenOCD Developer Resources -* JTAG Hardware Dongles:: JTAG Hardware Dongles +* Debug Adapter Hardware:: Debug Adapter Hardware * About JIM-Tcl:: About JIM-Tcl * Running:: Running OpenOCD * OpenOCD Project Setup:: OpenOCD Project Setup * Config File Guidelines:: Config File Guidelines * Daemon Configuration:: Daemon Configuration -* Interface - Dongle Configuration:: Interface - Dongle Configuration +* Debug Adapter Configuration:: Debug Adapter Configuration * Reset Configuration:: Reset Configuration * TAP Declaration:: TAP Declaration * CPU Configuration:: CPU Configuration @@ -111,15 +111,47 @@ The Open On-Chip Debugger (OpenOCD) aims to provide debugging, in-system programming and boundary-scan testing for embedded target devices. -@b{JTAG:} OpenOCD uses a ``hardware interface dongle'' to communicate -with the JTAG (IEEE 1149.1) compliant TAPs on your target board. +It does so with the assistance of a @dfn{debug adapter}, which is +a small hardware module which helps provide the right kind of +electrical signaling to the target being debugged. These are +required since the debug host (on which OpenOCD runs) won't +usually have native support for such signaling, or the connector +needed to hook up to the target. + +Such debug adapters support one or more @dfn{transport} protocols, +each of which involves different electrical signaling (and uses +different messaging protocols on top of that signaling). There +are many types of debug adapter, and little uniformity in what +they are called. (There are also product naming differences.) + +These adapters are sometimes packaged as discrete dongles. which +may generically be called @dfn{hardware interface dongles}. +Some development boards also integrate them directly, which may +let the development board can be directly connected to the debug +host over USB (and sometimes also to power it over USB). + +For example, a @dfn{JTAG Adapter} supports JTAG +signaling, and is used to communicate +with JTAG (IEEE 1149.1) compliant TAPs on your target board. A @dfn{TAP} is a ``Test Access Port'', a module which processes special instructions and data. TAPs are daisy-chained within and -between chips and boards. +between chips and boards. JTAG supports debugging and boundary +scan operations. + +There are also @dfn{SWD Adapters} that support Serial Wire Debug (SWD) +signaling to communicate with some newer ARM cores, as well as debug +adapters which support both JTAG and SWD transports. SWD only supports +debugging, whereas JTAG also supports boundary scan operations. + +For some chips, there are also @dfn{Programming Adapters} supporting +special transports used only to write code to flash memory, without +support for on-chip debugging or boundary scan. +(At this writing, OpenOCD does not support such non-debug adapters.) + @b{Dongles:} OpenOCD currently supports many types of hardware dongles: USB based, parallel port based, and other standalone boxes that run -OpenOCD internally. @xref{JTAG Hardware Dongles}. +OpenOCD internally. @xref{Debug Adapter Hardware}. @b{GDB Debug:} It allows ARM7 (ARM7TDMI and ARM720t), ARM9 (ARM920T, ARM922T, ARM926EJ--S, ARM966E--S), XScale (PXA25x, IXP42x) and @@ -234,8 +266,8 @@ using Trac for its bug database: @uref{https://sourceforge.net/apps/trac/openocd} -@node JTAG Hardware Dongles -@chapter JTAG Hardware Dongles +@node Debug Adapter Hardware +@chapter Debug Adapter Hardware @cindex dongles @cindex FTDI @cindex wiggler @@ -247,9 +279,9 @@ using Trac for its bug database: Defined: @b{dongle}: A small device that plugins into a computer and serves as an adapter .... [snip] -In the OpenOCD case, this generally refers to @b{a small adapater} one -attaches to your computer via USB or the Parallel Printer Port. The -execption being the Zylin ZY1000 which is a small box you attach via +In the OpenOCD case, this generally refers to @b{a small adapter} that +attaches to your computer via USB or the Parallel Printer Port. One +exception is the Zylin ZY1000, packaged as a small box you attach via an ethernet cable. The Zylin ZY1000 has the advantage that it does not require any drivers to be installed on the developer PC. It also has a built in web interface. It supports RTCK/RCLK or adaptive clocking @@ -261,6 +293,9 @@ and has a built in relay to power cycle targets remotely. There are several things you should keep in mind when choosing a dongle. @enumerate +@item @b{Transport} Does it support the kind of communication that you need? +OpenOCD focusses mostly on JTAG. Your version may also support +other ways to communicate with target devices. @item @b{Voltage} What voltage is your target - 1.8, 2.8, 3.3, or 5V? Does your dongle support it? You might need a level converter. @item @b{Pinout} What pinout does your target board use? @@ -268,7 +303,8 @@ Does your dongle support it? You may be able to use jumper wires, or an "octopus" connector, to convert pinouts. @item @b{Connection} Does your computer have the USB, printer, or Ethernet port needed? -@item @b{RTCK} Do you require RTCK? Also known as ``adaptive clocking'' +@item @b{RTCK} Do you expect to use it with ARM chips and boards with +RTCK support? Also known as ``adaptive clocking'' @end enumerate @section Stand alone Systems @@ -286,7 +322,17 @@ on a chip from ``Future Technology Devices International'' (FTDI) known as the FTDI FT2232; this is a USB full speed (12 Mbps) chip. See: @url{http://www.ftdichip.com} for more information. In summer 2009, USB high speed (480 Mbps) versions of these FTDI -chips are starting to become available in JTAG adapters. +chips are starting to become available in JTAG adapters. (Adapters +using those high speed FT2232H chips may support adaptive clocking.) + +The FT2232 chips are flexible enough to support some other +transport options, such as SWD or the SPI variants used to +program some chips. They have two communications channels, +and one can be used for a UART adapter at the same time the +other one is used to provide a debug adapter. + +Also, some development boards integrate an FT2232 chip to serve as +a built-in low coast debug adapter and usb-to-serial solution. @itemize @bullet @item @b{usbjtag} @@ -303,11 +349,11 @@ chips are starting to become available in JTAG adapters. @* See: @url{http://www.luminarymicro.com} - The Stellaris eval boards bundle FT2232-based JTAG and SWD support, which can be used to debug the Stellaris chips. Using separate JTAG adapters is optional. -These boards can also be used as JTAG adapters to other target boards, -disabling the Stellaris chip. +These boards can also be used in a "pass through" mode as JTAG adapters +to other target boards, disabling the Stellaris chip. @item @b{Luminary ICDI} @* See: @url{http://www.luminarymicro.com} - Luminary In-Circuit Debug -Interface (ICDI) Boards are included in Stellaris LM3S9B90 and LM3S9B92 +Interface (ICDI) Boards are included in Stellaris LM3S9B9x Evaluation Kits. Like the non-detachable FT2232 support on the other Stellaris eval boards, they can be used to debug other target boards. @item @b{olimex-jtag} @@ -507,7 +553,7 @@ as Tcl scripts, from a @file{startup.tcl} file internal to the server. @cindex directory search Properly installing OpenOCD sets up your operating system to grant it access -to the JTAG adapters. On Linux, this usually involves installing a file +to the debug adapters. On Linux, this usually involves installing a file in @file{/etc/udev/rules.d,} so OpenOCD has permissions. MS-Windows needs complex and confusing driver configuration for every peripheral. Such issues are unique to each operating system, and are not detailed in this User's Guide. @@ -798,7 +844,7 @@ Three main types of non-user configuration file each have their own subdirectory in the @file{scripts} directory: @enumerate -@item @b{interface} -- one for each kind of JTAG adapter/dongle +@item @b{interface} -- one for each different debug adapter; @item @b{board} -- one for each different board @item @b{target} -- the chips which integrate CPUs and other JTAG TAPs @end enumerate @@ -823,7 +869,8 @@ the board differences are encapsulated by application code. @item Maybe you don't know yet what your board looks like to JTAG. Once you know the @file{interface.cfg} file to use, you may need help from OpenOCD to discover what's on the board. -Once you find the TAPs, you can just search for appropriate +Once you find the JTAG TAPs, you can just search for appropriate +target and board configuration files ... or write your own, from the bottom up. @xref{Autoprobing}. @@ -849,7 +896,7 @@ will help support users of any board using that chip. @item You may may need to write some C code. It may be as simple as a supporting a new ft2232 or parport -based dongle; a bit more involved, like a NAND or NOR flash +based adapter; a bit more involved, like a NAND or NOR flash controller driver; or a big piece of work like supporting a new chip architecture. @end itemize @@ -1141,7 +1188,8 @@ with files including the ones listed here. Use them as-is where you can; or as models for new files. @itemize @bullet @item @file{interface} ... -think JTAG Dongle. Files that configure JTAG adapters go here. +These are for debug adapters. +Files that configure JTAG adapters go here. @example $ ls interface arm-jtag-ew.cfg hitex_str9-comstick.cfg oocdlink.cfg @@ -1252,13 +1300,15 @@ should be able to source one of these files with a command like this: source [find interface/FOOBAR.cfg] @end example -A preconfigured interface file should exist for every interface in use -today, that said, perhaps some interfaces have only been used by the -sole developer who created it. +A preconfigured interface file should exist for every debug adapter +in use today with OpenOCD. +That said, perhaps some of these config files +have only been used by the developer who created it. A separate chapter gives information about how to set these up. -@xref{Interface - Dongle Configuration}. -Read the OpenOCD source code if you have a new kind of hardware interface +@xref{Debug Adapter Configuration}. +Read the OpenOCD source code (and Developer's GUide) +if you have a new kind of hardware interface and need to provide a driver for it. @section Board Config Files @@ -1987,16 +2037,26 @@ MMU: disabled, D-Cache: disabled, I-Cache: enabled @end example @end deffn -@node Interface - Dongle Configuration -@chapter Interface - Dongle Configuration +@node Debug Adapter Configuration +@chapter Debug Adapter Configuration @cindex config file, interface @cindex interface config file Correctly installing OpenOCD includes making your operating system give -OpenOCD access to JTAG adapters. Once that has been done, Tcl commands +OpenOCD access to debug adapters. Once that has been done, Tcl commands are used to select which one is used, and to configure how it is used. -JTAG Adapters/Interfaces/Dongles are normally configured +@quotation Note +Because OpenOCD started out with a focus purely on JTAG, you may find +places where it wrongly presumes JTAG is the only transport protocol +in use. Be aware that recent versions of OpenOCD are removing that +limitation. JTAG remains more functional than most other transports. +Other transports do not support boundary scan operations, or may be +specific to a given chip vendor. Some might be usable only for +programming flash memory, instead of also for debugging. +@end quotation + +Debug Adapters/Interfaces/Dongles are normally configured through commands in an interface configuration file which is sourced by your @file{openocd.cfg} file, or through a command line @option{-f interface/....cfg} option. @@ -2019,9 +2079,9 @@ Most adapters need a bit more configuration than that. @section Interface Configuration -The interface command tells OpenOCD what type of JTAG dongle you are -using. Depending on the type of dongle, you may need to have one or -more additional commands. +The interface command tells OpenOCD what type of debug adapter you are +using. Depending on the type of adapter, you may need to use one or +more additional commands to further identify or configure the adapter. @deffn {Config Command} {interface} name Use the interface driver @var{name} to connect to the @@ -7161,8 +7221,8 @@ that 5 MHz JTAG clock be usable? @b{Solution #1 - A special circuit} In order to make use of this, -both your CPU and your JTAG dongle must support the RTCK -feature. Not all dongles support this - keep reading! +your CPU, board, and JTAG adapter must all support the RTCK +feature. Not all of them support this; keep reading! The RTCK ("Return TCK") signal in some ARM chips is used to help with this problem. ARM has a good description of the problem described at @@ -7198,7 +7258,9 @@ depending on the chips on your board. ARM11 cores use an 8:1 division. @b{Xilinx rule of thumb} is 1/12 the clock speed. -Note: Many FTDI2232C based JTAG dongles are limited to 6MHz. +Note: most full speed FT2232 based JTAG adapters are limited to a +maximum of 6MHz. The ones using USB high speed chips (FT2232H) +often support faster clock rates (and adaptive clocking). You can still debug the 'low power' situations - you just need to either use a fixed and very slow JTAG clock rate ... or else diff --git a/tcl/board/at91sam9g20-ek.cfg b/tcl/board/at91sam9g20-ek.cfg index b0fe546..fb6068c 100644 --- a/tcl/board/at91sam9g20-ek.cfg +++ b/tcl/board/at91sam9g20-ek.cfg @@ -28,8 +28,9 @@ reset_config trst_and_srst jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID -# Use caution changing the delays listed below. These seem to be affected by the board and type of -# debugger dongle. A value of 200 ms seems to work reliably for the configuration listed in the file header above. +# Use caution changing the delays listed below. These seem to be +# affected by the board and type of JTAG adapter. A value of 200 ms seems +# to work reliably for the configuration listed in the file header above. jtag_nsrst_delay 200 jtag_ntrst_delay 200 commit 74113cf72570a20f5f2ff66f721284bd4228aee3 Author: David Brownell <dbr...@us...> Date: Fri Mar 5 13:08:11 2010 -0800 README: update libftdi version The FT2232H really wants libftdi 0.17 or newer; some notable bugs got fixed in that version. Signed-off-by: David Brownell <dbr...@us...> diff --git a/README b/README index b69a69a..a683476 100644 --- a/README +++ b/README @@ -317,7 +317,7 @@ The libftdi source code can be download from the following website: For both Linux and Windows, both libusb and libftdi must be built and installed. To use the newer FT2232H chips, supporting RTCK and USB high -speed (480 Mbps), you need libftdi version 0.16 or newer. Many Linux +speed (480 Mbps), use libftdi version 0.17 or newer. Many Linux distributions provide suitable packages for these libraries. For Windows, libftdi is supported with versions 0.14 and later. ----------------------------------------------------------------------- Summary of changes: README | 2 +- doc/manual/server.txt | 8 +- doc/openocd.texi | 134 ++++++++++++++++++++++++++++++----------- tcl/board/at91sam9g20-ek.cfg | 5 +- 4 files changed, 106 insertions(+), 43 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-03-05 19:39:51
|
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 d33a81c549743e13633db9e8749f0e7cb0f7324b (commit) from 57ebf6d3dea85d7c4d712a1ada161d76096fdf23 (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 d33a81c549743e13633db9e8749f0e7cb0f7324b Author: David Brownell <dbr...@us...> Date: Fri Mar 5 10:39:25 2010 -0800 ADIv5 share DAP command support Get rid of needless and undesirable code duplication for all the DAP commands (resolving a FIXME) ... there's no need for coreas to have private copies of that stuff. Stick a pointer to the DAP in "struct arm", letting common code get to it. Also rename the "swjdp_info" symbol; just call it "dap". This is an overall code shrink. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm.h b/src/target/arm.h index ee4bd76..99bd983 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -167,6 +167,12 @@ struct arm { uint32_t value); void *arch_info; + + /** For targets conforming to ARM Debug Interface v5, + * this handle references the Debug Access Port (DAP) + * used to make requests to the target. + */ + struct adiv5_dap *dap; }; /** Convert target handle to generic ARM target state handle. */ diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index e30ddf6..1c52786 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -69,6 +69,7 @@ #include "config.h" #endif +#include "arm.h" #include "arm_adi_v5.h" #include <helper/time_support.h> @@ -1352,7 +1353,7 @@ is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0) && ((cid1 & 0x0f) == 0) && cid0 == 0x0d; } -int dap_info_command(struct command_context *cmd_ctx, +static int dap_info_command(struct command_context *cmd_ctx, struct adiv5_dap *swjdp, int apsel) { int retval; @@ -1711,15 +1712,40 @@ int dap_info_command(struct command_context *cmd_ctx, return ERROR_OK; } -DAP_COMMAND_HANDLER(dap_baseaddr_command) +COMMAND_HANDLER(handle_dap_info_command) { + struct target *target = get_current_target(CMD_CTX); + struct arm *arm = target_to_arm(target); + struct adiv5_dap *dap = arm->dap; + uint32_t apsel; + + switch (CMD_ARGC) { + case 0: + apsel = dap->apsel; + break; + case 1: + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; + } + + return dap_info_command(CMD_CTX, dap, apsel); +} + +COMMAND_HANDLER(dap_baseaddr_command) +{ + struct target *target = get_current_target(CMD_CTX); + struct arm *arm = target_to_arm(target); + struct adiv5_dap *dap = arm->dap; + uint32_t apsel, apselsave, baseaddr; int retval; - apselsave = swjdp->apsel; + apselsave = dap->apsel; switch (CMD_ARGC) { case 0: - apsel = swjdp->apsel; + apsel = dap->apsel; break; case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); @@ -1732,33 +1758,37 @@ DAP_COMMAND_HANDLER(dap_baseaddr_command) } if (apselsave != apsel) - dap_ap_select(swjdp, apsel); + dap_ap_select(dap, apsel); /* NOTE: assumes we're talking to a MEM-AP, which * has a base address. There are other kinds of AP, * though they're not common for now. This should * use the ID register to verify it's a MEM-AP. */ - retval = dap_queue_ap_read(swjdp, AP_REG_BASE, &baseaddr); - retval = dap_run(swjdp); + retval = dap_queue_ap_read(dap, AP_REG_BASE, &baseaddr); + retval = dap_run(dap); if (retval != ERROR_OK) return retval; command_print(CMD_CTX, "0x%8.8" PRIx32, baseaddr); if (apselsave != apsel) - dap_ap_select(swjdp, apselsave); + dap_ap_select(dap, apselsave); return retval; } -DAP_COMMAND_HANDLER(dap_memaccess_command) +COMMAND_HANDLER(dap_memaccess_command) { + struct target *target = get_current_target(CMD_CTX); + struct arm *arm = target_to_arm(target); + struct adiv5_dap *dap = arm->dap; + uint32_t memaccess_tck; switch (CMD_ARGC) { case 0: - memaccess_tck = swjdp->memaccess_tck; + memaccess_tck = dap->memaccess_tck; break; case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck); @@ -1766,16 +1796,20 @@ DAP_COMMAND_HANDLER(dap_memaccess_command) default: return ERROR_COMMAND_SYNTAX_ERROR; } - swjdp->memaccess_tck = memaccess_tck; + dap->memaccess_tck = memaccess_tck; command_print(CMD_CTX, "memory bus access delay set to %" PRIi32 " tck", - swjdp->memaccess_tck); + dap->memaccess_tck); return ERROR_OK; } -DAP_COMMAND_HANDLER(dap_apsel_command) +COMMAND_HANDLER(dap_apsel_command) { + struct target *target = get_current_target(CMD_CTX); + struct arm *arm = target_to_arm(target); + struct adiv5_dap *dap = arm->dap; + uint32_t apsel, apid; int retval; @@ -1793,9 +1827,9 @@ DAP_COMMAND_HANDLER(dap_apsel_command) return ERROR_COMMAND_SYNTAX_ERROR; } - dap_ap_select(swjdp, apsel); - retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &apid); - retval = dap_run(swjdp); + dap_ap_select(dap, apsel); + retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid); + retval = dap_run(dap); if (retval != ERROR_OK) return retval; @@ -1805,15 +1839,19 @@ DAP_COMMAND_HANDLER(dap_apsel_command) return retval; } -DAP_COMMAND_HANDLER(dap_apid_command) +COMMAND_HANDLER(dap_apid_command) { + struct target *target = get_current_target(CMD_CTX); + struct arm *arm = target_to_arm(target); + struct adiv5_dap *dap = arm->dap; + uint32_t apsel, apselsave, apid; int retval; - apselsave = swjdp->apsel; + apselsave = dap->apsel; switch (CMD_ARGC) { case 0: - apsel = swjdp->apsel; + apsel = dap->apsel; break; case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); @@ -1826,20 +1864,75 @@ DAP_COMMAND_HANDLER(dap_apid_command) } if (apselsave != apsel) - dap_ap_select(swjdp, apsel); + dap_ap_select(dap, apsel); - retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &apid); - retval = dap_run(swjdp); + retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid); + retval = dap_run(dap); if (retval != ERROR_OK) return retval; command_print(CMD_CTX, "0x%8.8" PRIx32, apid); if (apselsave != apsel) - dap_ap_select(swjdp, apselsave); + dap_ap_select(dap, apselsave); return retval; } +static const struct command_registration dap_commands[] = { + { + .name = "info", + .handler = handle_dap_info_command, + .mode = COMMAND_EXEC, + .help = "display ROM table for MEM-AP " + "(default currently selected AP)", + .usage = "[ap_num]", + }, + { + .name = "apsel", + .handler = dap_apsel_command, + .mode = COMMAND_EXEC, + .help = "Set the currently selected AP (default 0) " + "and display the result", + .usage = "[ap_num]", + }, + { + .name = "apid", + .handler = dap_apid_command, + .mode = COMMAND_EXEC, + .help = "return ID register from AP " + "(default currently selected AP)", + .usage = "[ap_num]", + }, + { + .name = "baseaddr", + .handler = dap_baseaddr_command, + .mode = COMMAND_EXEC, + .help = "return debug base address from MEM-AP " + "(default currently selected AP)", + .usage = "[ap_num]", + }, + { + .name = "memaccess", + .handler = dap_memaccess_command, + .mode = COMMAND_EXEC, + .help = "set/get number of extra tck for MEM-AP memory " + "bus access [0-255]", + .usage = "[cycles]", + }, + COMMAND_REGISTRATION_DONE +}; + +const struct command_registration dap_command_handlers[] = { + { + .name = "dap", + .mode = COMMAND_EXEC, + .help = "DAP command group", + .chain = dap_commands, + }, + COMMAND_REGISTRATION_DONE +}; + + /* * This represents the bits which must be sent out on TMS/SWDIO to * switch a DAP implemented using an SWJ-DP module into SWD mode. diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index abdbd24..d207fd9 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -378,17 +378,6 @@ int mem_ap_write_buf_u32(struct adiv5_dap *swjdp, int ahbap_debugport_init(struct adiv5_dap *swjdp); -/* Commands for user dap access */ -int dap_info_command(struct command_context *cmd_ctx, - struct adiv5_dap *swjdp, int apsel); - -#define DAP_COMMAND_HANDLER(name) \ - COMMAND_HELPER(name, struct adiv5_dap *swjdp) -DAP_COMMAND_HANDLER(dap_baseaddr_command); -DAP_COMMAND_HANDLER(dap_memaccess_command); -DAP_COMMAND_HANDLER(dap_apsel_command); -DAP_COMMAND_HANDLER(dap_apid_command); - struct target; /* Put debug link into SWD mode */ @@ -397,4 +386,6 @@ int dap_to_swd(struct target *target); /* Put debug link into JTAG mode */ int dap_to_jtag(struct target *target); +extern const struct command_registration dap_command_handlers[]; + #endif diff --git a/src/target/armv7a.c b/src/target/armv7a.c index 92a373a..151deb4 100644 --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -117,115 +117,9 @@ int armv7a_arch_state(struct target *target) } -COMMAND_HANDLER(handle_dap_baseaddr_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; - - return CALL_COMMAND_HANDLER(dap_baseaddr_command, swjdp); -} - -COMMAND_HANDLER(handle_dap_memaccess_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; - - return CALL_COMMAND_HANDLER(dap_memaccess_command, swjdp); -} - -COMMAND_HANDLER(handle_dap_apsel_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; - - return CALL_COMMAND_HANDLER(dap_apsel_command, swjdp); -} - -COMMAND_HANDLER(handle_dap_apid_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; - - return CALL_COMMAND_HANDLER(dap_apid_command, swjdp); -} - -COMMAND_HANDLER(handle_dap_info_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; - uint32_t apsel; - - switch (CMD_ARGC) { - case 0: - apsel = swjdp->apsel; - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return dap_info_command(CMD_CTX, swjdp, apsel); -} - -/* FIXME this table should be part of generic DAP support, and - * be shared by the ARMv7-A/R and ARMv7-M support ... - */ -static const struct command_registration armv7a_exec_command_handlers[] = { - { - .name = "info", - .handler = handle_dap_info_command, - .mode = COMMAND_EXEC, - .help = "display ROM table for MEM-AP " - "(default currently selected AP)", - .usage = "[ap_num]", - }, - { - .name = "apsel", - .handler = handle_dap_apsel_command, - .mode = COMMAND_EXEC, - .help = "Set the currently selected AP (default 0) " - "and display the result", - .usage = "[ap_num]", - }, - { - .name = "apid", - .handler = handle_dap_apid_command, - .mode = COMMAND_EXEC, - .help = "return ID register from AP " - "(default currently selected AP)", - .usage = "[ap_num]", - }, - { - .name = "baseaddr", - .handler = handle_dap_baseaddr_command, - .mode = COMMAND_EXEC, - .help = "return debug base address from MEM-AP " - "(default currently selected AP)", - .usage = "[ap_num]", - }, - { - .name = "memaccess", - .handler = handle_dap_memaccess_command, - .mode = COMMAND_EXEC, - .help = "set/get number of extra tck for MEM-AP memory " - "bus access [0-255]", - .usage = "[cycles]", - }, - COMMAND_REGISTRATION_DONE -}; const struct command_registration armv7a_command_handlers[] = { { - .name = "dap", - .mode = COMMAND_ANY, - .help = "Cortex DAP command group", - .chain = armv7a_exec_command_handlers, + .chain = dap_command_handlers, }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/armv7a.h b/src/target/armv7a.h index 70a2d9e..5ef8c42 100644 --- a/src/target/armv7a.h +++ b/src/target/armv7a.h @@ -50,8 +50,7 @@ struct armv7a_common int common_magic; struct reg_cache *core_cache; - /* arm adp debug port */ - struct adiv5_dap swjdp_info; + struct adiv5_dap dap; /* Core Debug Unit */ struct arm_dpm dpm; diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 5276af8..1216a45 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -739,160 +739,12 @@ int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found) return ERROR_OK; } -/*--------------------------------------------------------------------------*/ - -/* - * Only stuff below this line should need to verify that its target - * is an ARMv7-M node. - */ - - -/* - * Return the debug ap baseaddress in hexadecimal; - * no extra output to simplify script processing - */ -COMMAND_HANDLER(handle_dap_baseaddr_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; - - if (!is_armv7m(armv7m)) { - command_print(CMD_CTX, "current target isn't an ARM7-M"); - return ERROR_TARGET_INVALID; - } - - return CALL_COMMAND_HANDLER(dap_baseaddr_command, swjdp); -} - -/* - * Return the debug ap id in hexadecimal; - * no extra output to simplify script processing - */ -COMMAND_HANDLER(handle_dap_apid_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; - - if (!is_armv7m(armv7m)) { - command_print(CMD_CTX, "current target isn't an ARM7-M"); - return ERROR_TARGET_INVALID; - } - - return CALL_COMMAND_HANDLER(dap_apid_command, swjdp); -} - -COMMAND_HANDLER(handle_dap_apsel_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; - - if (!is_armv7m(armv7m)) { - command_print(CMD_CTX, "current target isn't an ARM7-M"); - return ERROR_TARGET_INVALID; - } - - return CALL_COMMAND_HANDLER(dap_apsel_command, swjdp); -} - -COMMAND_HANDLER(handle_dap_memaccess_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; - - if (!is_armv7m(armv7m)) { - command_print(CMD_CTX, "current target isn't an ARM7-M"); - return ERROR_TARGET_INVALID; - } - - return CALL_COMMAND_HANDLER(dap_memaccess_command, swjdp); -} - - -COMMAND_HANDLER(handle_dap_info_command) -{ - struct target *target = get_current_target(CMD_CTX); - struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; - uint32_t apsel; - - if (!is_armv7m(armv7m)) { - command_print(CMD_CTX, "current target isn't an ARM7-M"); - return ERROR_TARGET_INVALID; - } - - switch (CMD_ARGC) { - case 0: - apsel = swjdp->apsel; - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - - return dap_info_command(CMD_CTX, swjdp, apsel); -} - -/* FIXME this table should be part of generic DAP support, and - * be shared by the ARMv7-A/R and ARMv7-M support ... - */ -static const struct command_registration armv7m_exec_command_handlers[] = { - { - .name = "info", - .handler = handle_dap_info_command, - .mode = COMMAND_EXEC, - .help = "display ROM table for MEM-AP " - "(default currently selected AP)", - .usage = "[ap_num]", - }, - { - .name = "apsel", - .handler = handle_dap_apsel_command, - .mode = COMMAND_EXEC, - .help = "Set the currently selected AP (default 0) " - "and display the result", - .usage = "[ap_num]", - }, - { - .name = "apid", - .handler = handle_dap_apid_command, - .mode = COMMAND_EXEC, - .help = "return ID register from AP " - "(default currently selected AP)", - .usage = "[ap_num]", - }, - { - .name = "baseaddr", - .handler = handle_dap_baseaddr_command, - .mode = COMMAND_EXEC, - .help = "return debug base address from MEM-AP " - "(default currently selected AP)", - .usage = "[ap_num]", - }, - { - .name = "memaccess", - .handler = handle_dap_memaccess_command, - .mode = COMMAND_EXEC, - .help = "set/get number of extra tck for MEM-AP memory " - "bus access [0-255]", - .usage = "[cycles]", - }, - COMMAND_REGISTRATION_DONE -}; const struct command_registration armv7m_command_handlers[] = { { .chain = arm_command_handlers, }, { - .name = "dap", - .mode = COMMAND_EXEC, - .help = "Cortex DAP command group", - .chain = armv7m_exec_command_handlers, + .chain = dap_command_handlers, }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 5526505..51d6704 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -106,7 +106,7 @@ struct armv7m_common struct reg_cache *core_cache; enum armv7m_mode core_mode; int exception_number; - struct adiv5_dap swjdp_info; + struct adiv5_dap dap; uint32_t demcr; diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c index 0dc7cee..332a55a 100644 --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -67,7 +67,7 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, static int cortex_a8_init_debug_access(struct target *target) { struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; int retval; uint32_t dummy; @@ -103,7 +103,7 @@ static int cortex_a8_exec_opcode(struct target *target, uint32_t dscr; int retval; struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; dscr = dscr_p ? *dscr_p : 0; @@ -150,7 +150,7 @@ static int cortex_a8_read_regs_through_mem(struct target *target, uint32_t addre { int retval = ERROR_OK; struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; cortex_a8_dap_read_coreregister_u32(target, regfile, 0); cortex_a8_dap_write_coreregister_u32(target, address, 0); @@ -169,7 +169,7 @@ static int cortex_a8_dap_read_coreregister_u32(struct target *target, uint8_t reg = regnum&0xFF; uint32_t dscr = 0; struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; if (reg > 17) return retval; @@ -221,7 +221,7 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, uint8_t Rd = regnum&0xFF; uint32_t dscr; struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value); @@ -284,7 +284,7 @@ static int cortex_a8_dap_write_memap_register_u32(struct target *target, uint32_ { int retval; struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; retval = mem_ap_write_atomic_u32(swjdp, address, value); @@ -310,14 +310,14 @@ static inline struct cortex_a8_common *dpm_to_a8(struct arm_dpm *dpm) static int cortex_a8_write_dcc(struct cortex_a8_common *a8, uint32_t data) { LOG_DEBUG("write DCC 0x%08" PRIx32, data); - return mem_ap_write_u32(&a8->armv7a_common.swjdp_info, + return mem_ap_write_u32(&a8->armv7a_common.dap, a8->armv7a_common.debug_base + CPUDBG_DTRRX, data); } static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data, uint32_t *dscr_p) { - struct adiv5_dap *swjdp = &a8->armv7a_common.swjdp_info; + struct adiv5_dap *swjdp = &a8->armv7a_common.dap; uint32_t dscr = DSCR_INSTR_COMP; int retval; @@ -344,7 +344,7 @@ static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data, static int cortex_a8_dpm_prepare(struct arm_dpm *dpm) { struct cortex_a8_common *a8 = dpm_to_a8(dpm); - struct adiv5_dap *swjdp = &a8->armv7a_common.swjdp_info; + struct adiv5_dap *swjdp = &a8->armv7a_common.dap; uint32_t dscr; int retval; @@ -562,7 +562,7 @@ static int cortex_a8_poll(struct target *target) uint32_t dscr; struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = &cortex_a8->armv7a_common; - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; enum target_state prev_target_state = target->state; uint8_t saved_apsel = dap_ap_get_select(swjdp); @@ -626,7 +626,7 @@ static int cortex_a8_halt(struct target *target) int retval = ERROR_OK; uint32_t dscr; struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; uint8_t saved_apsel = dap_ap_get_select(swjdp); dap_ap_select(swjdp, swjdp_debugap); @@ -664,7 +664,7 @@ static int cortex_a8_resume(struct target *target, int current, { struct armv7a_common *armv7a = target_to_armv7a(target); struct arm *armv4_5 = &armv7a->armv4_5_common; - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; // struct breakpoint *breakpoint = NULL; uint32_t resume_pc, dscr; @@ -788,7 +788,7 @@ static int cortex_a8_debug_entry(struct target *target) struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = target_to_armv7a(target); struct arm *armv4_5 = &armv7a->armv4_5_common; - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; struct reg *reg; LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr); @@ -1276,7 +1276,7 @@ static int cortex_a8_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; int retval = ERROR_INVALID_ARGUMENTS; /* cortex_a8 handles unaligned memory access */ @@ -1304,7 +1304,7 @@ static int cortex_a8_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; int retval = ERROR_INVALID_ARGUMENTS; // ??? dap_ap_select(swjdp, swjdp_memoryap); @@ -1413,7 +1413,7 @@ static int cortex_a8_handle_target_request(void *priv) { struct target *target = priv; struct armv7a_common *armv7a = target_to_armv7a(target); - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; if (!target_was_examined(target)) return ERROR_OK; @@ -1455,7 +1455,7 @@ static int cortex_a8_examine_first(struct target *target) { struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = &cortex_a8->armv7a_common; - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->dap; int i; int retval = ERROR_OK; uint32_t didr, ctypr, ttypr, cpuid; @@ -1562,7 +1562,9 @@ static int cortex_a8_init_arch_info(struct target *target, { struct armv7a_common *armv7a = &cortex_a8->armv7a_common; struct arm *armv4_5 = &armv7a->armv4_5_common; - struct adiv5_dap *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *dap = &armv7a->dap; + + armv7a->armv4_5_common.dap = dap; /* Setup struct cortex_a8_common */ cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC; @@ -1573,11 +1575,11 @@ static int cortex_a8_init_arch_info(struct target *target, cortex_a8->jtag_info.scann_size = 4; /* Leave (only) generic DAP stuff for debugport_init() */ - swjdp->jtag_info = &cortex_a8->jtag_info; - swjdp->memaccess_tck = 80; + dap->jtag_info = &cortex_a8->jtag_info; + dap->memaccess_tck = 80; /* Number of bits for tar autoincrement, impl. dep. at least 10 */ - swjdp->tar_autoincr_block = (1 << 10); + dap->tar_autoincr_block = (1 << 10); cortex_a8->fast_reg_read = 0; diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 852965c..d39d839 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -129,7 +129,7 @@ static int cortex_m3_write_debug_halt_mask(struct target *target, uint32_t mask_on, uint32_t mask_off) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap; /* mask off status bits */ cortex_m3->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off); @@ -142,7 +142,7 @@ static int cortex_m3_write_debug_halt_mask(struct target *target, static int cortex_m3_clear_halt(struct target *target) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap; /* clear step if any */ cortex_m3_write_debug_halt_mask(target, C_HALT, C_STEP); @@ -160,7 +160,7 @@ static int cortex_m3_clear_halt(struct target *target) static int cortex_m3_single_step_core(struct target *target) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap; uint32_t dhcsr_save; /* backup dhcsr reg */ @@ -191,7 +191,7 @@ static int cortex_m3_endreset_event(struct target *target) uint32_t dcb_demcr; struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; - struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap; struct cortex_m3_fp_comparator *fp_list = cortex_m3->fp_comparator_list; struct cortex_m3_dwt_comparator *dwt_list = cortex_m3->dwt_comparator_list; @@ -286,7 +286,7 @@ static int cortex_m3_examine_exception_reason(struct target *target) { uint32_t shcsr, except_sr, cfsr = -1, except_ar = -1; struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; int retval; mem_ap_read_u32(swjdp, NVIC_SHCSR, &shcsr); @@ -360,7 +360,7 @@ static int cortex_m3_debug_entry(struct target *target) struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; struct arm *arm = &armv7m->arm; - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; struct reg *r; LOG_DEBUG(" "); @@ -452,7 +452,7 @@ static int cortex_m3_poll(struct target *target) int retval; enum target_state prev_target_state = target->state; struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap; /* Read from Debug Halting Control and Status Register */ retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); @@ -587,7 +587,7 @@ static int cortex_m3_halt(struct target *target) static int cortex_m3_soft_reset_halt(struct target *target) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap; uint32_t dcb_dhcsr = 0; int retval, timeout = 0; @@ -761,7 +761,7 @@ static int cortex_m3_step(struct target *target, int current, { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; struct breakpoint *breakpoint = NULL; struct reg *pc = armv7m->arm.pc; bool bkpt_inst_found = false; @@ -826,7 +826,7 @@ static int cortex_m3_step(struct target *target, int current, static int cortex_m3_assert_reset(struct target *target) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap; int assert_srst = 1; LOG_DEBUG("target->state: %s", @@ -1376,7 +1376,7 @@ static int cortex_m3_load_core_reg_u32(struct target *target, { int retval; struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; /* NOTE: we "know" here that the register identifiers used * in the v7m header match the Cortex-M3 Debug Core Register @@ -1440,7 +1440,7 @@ static int cortex_m3_store_core_reg_u32(struct target *target, int retval; uint32_t reg; struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; #ifdef ARMV7_GDB_HACKS /* If the LR register is being modified, make sure it will put us @@ -1518,7 +1518,7 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; int retval = ERROR_INVALID_ARGUMENTS; /* cortex_m3 handles unaligned memory access */ @@ -1543,7 +1543,7 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; int retval = ERROR_INVALID_ARGUMENTS; if (count && buffer) { @@ -1724,7 +1724,7 @@ static int cortex_m3_examine(struct target *target) uint32_t cpuid, fpcr; int i; struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.dap; if ((retval = ahbap_debugport_init(swjdp)) != ERROR_OK) return retval; @@ -1798,7 +1798,7 @@ static int cortex_m3_target_request_data(struct target *target, uint32_t size, uint8_t *buffer) { struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; uint8_t data; uint8_t ctrl; uint32_t i; @@ -1818,7 +1818,7 @@ static int cortex_m3_handle_target_request(void *priv) if (!target_was_examined(target)) return ERROR_OK; struct armv7m_common *armv7m = target_to_armv7m(target); - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; if (!target->dbg_msg_enabled) return ERROR_OK; @@ -1862,11 +1862,13 @@ static int cortex_m3_init_arch_info(struct target *target, cortex_m3->jtag_info.tap = tap; cortex_m3->jtag_info.scann_size = 4; + armv7m->arm.dap = &armv7m->dap; + /* Leave (only) generic DAP stuff for debugport_init(); */ - armv7m->swjdp_info.jtag_info = &cortex_m3->jtag_info; - armv7m->swjdp_info.memaccess_tck = 8; + armv7m->dap.jtag_info = &cortex_m3->jtag_info; + armv7m->dap.memaccess_tck = 8; /* Cortex-M3 has 4096 bytes autoincrement range */ - armv7m->swjdp_info.tar_autoincr_block = (1 << 12); + armv7m->dap.tar_autoincr_block = (1 << 12); /* register arch-specific functions */ armv7m->examine_debug_reason = cortex_m3_examine_debug_reason; @@ -1936,7 +1938,7 @@ COMMAND_HANDLER(handle_cortex_m3_vector_catch_command) struct target *target = get_current_target(CMD_CTX); struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; - struct adiv5_dap *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->dap; uint32_t demcr = 0; int retval; ----------------------------------------------------------------------- Summary of changes: src/target/arm.h | 6 ++ src/target/arm_adi_v5.c | 139 ++++++++++++++++++++++++++++++++++++------- src/target/arm_adi_v5.h | 13 +---- src/target/armv7a.c | 108 +--------------------------------- src/target/armv7a.h | 3 +- src/target/armv7m.c | 150 +---------------------------------------------- src/target/armv7m.h | 2 +- src/target/cortex_a8.c | 44 +++++++------- src/target/cortex_m3.c | 44 +++++++------- 9 files changed, 174 insertions(+), 335 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: Øyvind H. <go...@us...> - 2010-03-05 10:37:19
|
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 57ebf6d3dea85d7c4d712a1ada161d76096fdf23 (commit) from 45a528ff3c0582f7d22b65d76d925f34a6956957 (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 57ebf6d3dea85d7c4d712a1ada161d76096fdf23 Author: Ãyvind Harboe <oyv...@zy...> Date: Thu Mar 4 18:30:03 2010 +0100 minidriver: fix arm11 compilation problem Signed-off-by: Ãyvind Harboe <oyv...@zy...> diff --git a/src/jtag/minidummy/minidummy.c b/src/jtag/minidummy/minidummy.c index 705f1b4..01cdd2e 100644 --- a/src/jtag/minidummy/minidummy.c +++ b/src/jtag/minidummy/minidummy.c @@ -163,3 +163,9 @@ void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, buffer += 4; } } + +int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count) +{ + int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count); + return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count); +} ----------------------------------------------------------------------- Summary of changes: src/jtag/minidummy/minidummy.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-03-05 06:52:59
|
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 45a528ff3c0582f7d22b65d76d925f34a6956957 (commit) from 5e78ddcea0d8303c316f687c05dfa78af27109d8 (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 45a528ff3c0582f7d22b65d76d925f34a6956957 Author: David Brownell <dbr...@us...> Date: Thu Mar 4 21:51:58 2010 -0800 rename "swjdp_common" as "adiv5_dap" This partially corrects an inappropriate name choice (and its associated FIXME). There are still too many variables named "swjdp", bug little current code actually relies on them referencing an SWJ-DP instead of some other flavor of DAP. Only the two new dap_to{swd,jtag}() calls could behave differently on an SWJ-DP instead of a SW-DP or a JTAG-DP. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index c5e0dd3..e30ddf6 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -108,7 +108,7 @@ static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address * @param invalue NULL, or points to a 32-bit (little-endian) integer * @param ack points to where the three bit JTAG_ACK_* code will be stored */ -static int adi_jtag_dp_scan(struct swjdp_common *swjdp, +static int adi_jtag_dp_scan(struct adiv5_dap *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint8_t *outvalue, uint8_t *invalue, uint8_t *ack) { @@ -161,7 +161,7 @@ static int adi_jtag_dp_scan(struct swjdp_common *swjdp, * conversions are performed (so the types of invalue and outvalue * must be different). */ -static int adi_jtag_dp_scan_u32(struct swjdp_common *swjdp, +static int adi_jtag_dp_scan_u32(struct adiv5_dap *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint32_t outvalue, uint32_t *invalue, uint8_t *ack) { @@ -185,14 +185,14 @@ static int adi_jtag_dp_scan_u32(struct swjdp_common *swjdp, /** * Utility to write AP registers. */ -static inline int adi_jtag_ap_write_check(struct swjdp_common *dap, +static inline int adi_jtag_ap_write_check(struct adiv5_dap *dap, uint8_t reg_addr, uint8_t *outvalue) { return adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg_addr, DPAP_WRITE, outvalue, NULL, NULL); } -static int adi_jtag_scan_inout_check_u32(struct swjdp_common *swjdp, +static int adi_jtag_scan_inout_check_u32(struct adiv5_dap *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint32_t outvalue, uint32_t *invalue) { @@ -213,7 +213,7 @@ static int adi_jtag_scan_inout_check_u32(struct swjdp_common *swjdp, return retval; } -static int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) +static int jtagdp_transaction_endcheck(struct adiv5_dap *swjdp) { int retval; uint32_t ctrlstat; @@ -367,7 +367,7 @@ static int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) * @param apsel Number of the AP to (implicitly) use with further * transactions. This normally identifies a MEM-AP. */ -void dap_ap_select(struct swjdp_common *swjdp,uint8_t apsel) +void dap_ap_select(struct adiv5_dap *swjdp,uint8_t apsel) { uint32_t select = (apsel << 24) & 0xFF000000; @@ -402,7 +402,7 @@ void dap_ap_select(struct swjdp_common *swjdp,uint8_t apsel) * * @return ERROR_OK if the transaction was properly queued, else a fault code. */ -int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar) +int dap_setup_accessport(struct adiv5_dap *swjdp, uint32_t csw, uint32_t tar) { int retval; @@ -440,7 +440,7 @@ int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar) * * @return ERROR_OK for success. Otherwise a fault code. */ -int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, +int mem_ap_read_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t *value) { int retval; @@ -468,7 +468,7 @@ int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, * @return ERROR_OK for success; *value holds the result. * Otherwise a fault code. */ -int mem_ap_read_atomic_u32(struct swjdp_common *swjdp, uint32_t address, +int mem_ap_read_atomic_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t *value) { int retval; @@ -491,7 +491,7 @@ int mem_ap_read_atomic_u32(struct swjdp_common *swjdp, uint32_t address, * * @return ERROR_OK for success. Otherwise a fault code. */ -int mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, +int mem_ap_write_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t value) { int retval; @@ -519,7 +519,7 @@ int mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, * * @return ERROR_OK for success; the data was written. Otherwise a fault code. */ -int mem_ap_write_atomic_u32(struct swjdp_common *swjdp, uint32_t address, +int mem_ap_write_atomic_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t value) { int retval = mem_ap_write_u32(swjdp, address, value); @@ -532,12 +532,12 @@ int mem_ap_write_atomic_u32(struct swjdp_common *swjdp, uint32_t address, /***************************************************************************** * * -* mem_ap_write_buf(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address) * +* mem_ap_write_buf(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) * * * * Write a buffer in target order (little endian) * * * *****************************************************************************/ -int mem_ap_write_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address) +int mem_ap_write_buf_u32(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { int wcount, blocksize, writecount, errorcount = 0, retval = ERROR_OK; uint32_t adr = address; @@ -608,7 +608,7 @@ int mem_ap_write_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, return retval; } -static int mem_ap_write_buf_packed_u16(struct swjdp_common *swjdp, +static int mem_ap_write_buf_packed_u16(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { int retval = ERROR_OK; @@ -688,7 +688,7 @@ static int mem_ap_write_buf_packed_u16(struct swjdp_common *swjdp, return retval; } -int mem_ap_write_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address) +int mem_ap_write_buf_u16(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { int retval = ERROR_OK; @@ -717,7 +717,7 @@ int mem_ap_write_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, return retval; } -static int mem_ap_write_buf_packed_u8(struct swjdp_common *swjdp, +static int mem_ap_write_buf_packed_u8(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { int retval = ERROR_OK; @@ -792,7 +792,7 @@ static int mem_ap_write_buf_packed_u8(struct swjdp_common *swjdp, return retval; } -int mem_ap_write_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address) +int mem_ap_write_buf_u8(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { int retval = ERROR_OK; @@ -827,7 +827,7 @@ int mem_ap_write_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, * @param address Memory address from which to read words; all the * words must be readable by the currently selected MEM-AP. */ -int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, +int mem_ap_read_buf_u32(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK; @@ -924,7 +924,7 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, return retval; } -static int mem_ap_read_buf_packed_u16(struct swjdp_common *swjdp, +static int mem_ap_read_buf_packed_u16(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { uint32_t invalue; @@ -984,7 +984,7 @@ static int mem_ap_read_buf_packed_u16(struct swjdp_common *swjdp, * @param address Memory address from which to read words; all the * words must be readable by the currently selected MEM-AP. */ -int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, +int mem_ap_read_buf_u16(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { uint32_t invalue, i; @@ -1032,7 +1032,7 @@ int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, * The solution is to arrange for a large out/in scan in this loop and * and convert data afterwards. */ -static int mem_ap_read_buf_packed_u8(struct swjdp_common *swjdp, +static int mem_ap_read_buf_packed_u8(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { uint32_t invalue; @@ -1089,7 +1089,7 @@ static int mem_ap_read_buf_packed_u8(struct swjdp_common *swjdp, * @param address Memory address from which to read data; all the * data must be readable by the currently selected MEM-AP. */ -int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, +int mem_ap_read_buf_u8(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address) { uint32_t invalue; @@ -1117,7 +1117,7 @@ int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, /*--------------------------------------------------------------------------*/ -static int jtag_idcode_q_read(struct swjdp_common *dap, +static int jtag_idcode_q_read(struct adiv5_dap *dap, uint8_t *ack, uint32_t *data) { struct arm_jtag *jtag_info = dap->jtag_info; @@ -1147,14 +1147,14 @@ static int jtag_idcode_q_read(struct swjdp_common *dap, return retval; } -static int jtag_dp_q_read(struct swjdp_common *dap, unsigned reg, +static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data) { return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC, reg, DPAP_READ, 0, data); } -static int jtag_dp_q_write(struct swjdp_common *dap, unsigned reg, +static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg, uint32_t data) { return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC, @@ -1162,7 +1162,7 @@ static int jtag_dp_q_write(struct swjdp_common *dap, unsigned reg, } /** Select the AP register bank matching bits 7:4 of reg. */ -static int jtag_ap_q_bankselect(struct swjdp_common *dap, unsigned reg) +static int jtag_ap_q_bankselect(struct adiv5_dap *dap, unsigned reg) { uint32_t select = reg & 0x000000F0; @@ -1175,7 +1175,7 @@ static int jtag_ap_q_bankselect(struct swjdp_common *dap, unsigned reg) return jtag_dp_q_write(dap, DP_SELECT, select); } -static int jtag_ap_q_read(struct swjdp_common *dap, unsigned reg, +static int jtag_ap_q_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data) { int retval = jtag_ap_q_bankselect(dap, reg); @@ -1187,7 +1187,7 @@ static int jtag_ap_q_read(struct swjdp_common *dap, unsigned reg, DPAP_READ, 0, data); } -static int jtag_ap_q_write(struct swjdp_common *dap, unsigned reg, +static int jtag_ap_q_write(struct adiv5_dap *dap, unsigned reg, uint32_t data) { uint8_t out_value_buf[4]; @@ -1201,14 +1201,14 @@ static int jtag_ap_q_write(struct swjdp_common *dap, unsigned reg, return adi_jtag_ap_write_check(dap, reg, out_value_buf); } -static int jtag_ap_q_abort(struct swjdp_common *dap, uint8_t *ack) +static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack) { /* for JTAG, this is the only valid ABORT register operation */ return adi_jtag_dp_scan_u32(dap, JTAG_DP_ABORT, 0, DPAP_WRITE, 1, NULL, ack); } -static int jtag_dp_run(struct swjdp_common *dap) +static int jtag_dp_run(struct adiv5_dap *dap) { return jtagdp_transaction_endcheck(dap); } @@ -1237,7 +1237,7 @@ static const struct dap_ops jtag_dp_ops = { * in layering. (JTAG is useful without any debug target; but not SWD.) * And this may not even use an AHB-AP ... e.g. DAP-Lite uses an APB-AP. */ -int ahbap_debugport_init(struct swjdp_common *swjdp) +int ahbap_debugport_init(struct adiv5_dap *swjdp) { uint32_t idreg, romaddr, dummy; uint32_t ctrlstat; @@ -1353,7 +1353,7 @@ is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0) } int dap_info_command(struct command_context *cmd_ctx, - struct swjdp_common *swjdp, int apsel) + struct adiv5_dap *swjdp, int apsel) { int retval; uint32_t dbgbase, apid; diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index e867b85..abdbd24 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -133,10 +133,8 @@ * a choice made at board design time (by only using the SWD pins), or * as part of setting up a debug session (if all the dual-role JTAG/SWD * signals are available). - * - * @todo Rename "swjdp_common" as "dap". Use of SWJ-DP is optional! */ -struct swjdp_common +struct adiv5_dap { const struct dap_ops *ops; @@ -201,27 +199,27 @@ struct dap_ops { bool is_swd; /** Reads the DAP's IDCODe register. */ - int (*queue_idcode_read)(struct swjdp_common *dap, + int (*queue_idcode_read)(struct adiv5_dap *dap, uint8_t *ack, uint32_t *data); /** DP register read. */ - int (*queue_dp_read)(struct swjdp_common *dap, unsigned reg, + int (*queue_dp_read)(struct adiv5_dap *dap, unsigned reg, uint32_t *data); /** DP register write. */ - int (*queue_dp_write)(struct swjdp_common *dap, unsigned reg, + int (*queue_dp_write)(struct adiv5_dap *dap, unsigned reg, uint32_t data); /** AP register read. */ - int (*queue_ap_read)(struct swjdp_common *dap, unsigned reg, + int (*queue_ap_read)(struct adiv5_dap *dap, unsigned reg, uint32_t *data); /** AP register write. */ - int (*queue_ap_write)(struct swjdp_common *dap, unsigned reg, + int (*queue_ap_write)(struct adiv5_dap *dap, unsigned reg, uint32_t data); /** AP operation abort. */ - int (*queue_ap_abort)(struct swjdp_common *dap, uint8_t *ack); + int (*queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack); /** Executes all queued DAP operations. */ - int (*run)(struct swjdp_common *dap); + int (*run)(struct adiv5_dap *dap); }; /** @@ -235,7 +233,7 @@ struct dap_ops { * * @return ERROR_OK for success, else a fault code. */ -static inline int dap_queue_idcode_read(struct swjdp_common *dap, +static inline int dap_queue_idcode_read(struct adiv5_dap *dap, uint8_t *ack, uint32_t *data) { return dap->ops->queue_idcode_read(dap, ack, data); @@ -253,7 +251,7 @@ static inline int dap_queue_idcode_read(struct swjdp_common *dap, * * @return ERROR_OK for success, else a fault code. */ -static inline int dap_queue_dp_read(struct swjdp_common *dap, +static inline int dap_queue_dp_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data) { return dap->ops->queue_dp_read(dap, reg, data); @@ -270,7 +268,7 @@ static inline int dap_queue_dp_read(struct swjdp_common *dap, * * @return ERROR_OK for success, else a fault code. */ -static inline int dap_queue_dp_write(struct swjdp_common *dap, +static inline int dap_queue_dp_write(struct adiv5_dap *dap, unsigned reg, uint32_t data) { return dap->ops->queue_dp_write(dap, reg, data); @@ -286,7 +284,7 @@ static inline int dap_queue_dp_write(struct swjdp_common *dap, * * @return ERROR_OK for success, else a fault code. */ -static inline int dap_queue_ap_read(struct swjdp_common *dap, +static inline int dap_queue_ap_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data) { return dap->ops->queue_ap_read(dap, reg, data); @@ -301,7 +299,7 @@ static inline int dap_queue_ap_read(struct swjdp_common *dap, * * @return ERROR_OK for success, else a fault code. */ -static inline int dap_queue_ap_write(struct swjdp_common *dap, +static inline int dap_queue_ap_write(struct adiv5_dap *dap, unsigned reg, uint32_t data) { return dap->ops->queue_ap_write(dap, reg, data); @@ -318,7 +316,7 @@ static inline int dap_queue_ap_write(struct swjdp_common *dap, * * @return ERROR_OK for success, else a fault code. */ -static inline int dap_queue_ap_abort(struct swjdp_common *dap, uint8_t *ack) +static inline int dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) { return dap->ops->queue_ap_abort(dap, ack); } @@ -333,59 +331,59 @@ static inline int dap_queue_ap_abort(struct swjdp_common *dap, uint8_t *ack) * * @return ERROR_OK for success, else a fault code. */ -static inline int dap_run(struct swjdp_common *dap) +static inline int dap_run(struct adiv5_dap *dap) { return dap->ops->run(dap); } /** Accessor for currently selected DAP-AP number (0..255) */ -static inline uint8_t dap_ap_get_select(struct swjdp_common *swjdp) +static inline uint8_t dap_ap_get_select(struct adiv5_dap *swjdp) { return (uint8_t)(swjdp ->apsel >> 24); } /* AP selection applies to future AP transactions */ -void dap_ap_select(struct swjdp_common *dap,uint8_t apsel); +void dap_ap_select(struct adiv5_dap *dap,uint8_t apsel); /* Queued AP transactions */ -int dap_setup_accessport(struct swjdp_common *swjdp, +int dap_setup_accessport(struct adiv5_dap *swjdp, uint32_t csw, uint32_t tar); /* Queued MEM-AP memory mapped single word transfers */ -int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t *value); -int mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t value); +int mem_ap_read_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t *value); +int mem_ap_write_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t value); /* Synchronous MEM-AP memory mapped single word transfers */ -int mem_ap_read_atomic_u32(struct swjdp_common *swjdp, +int mem_ap_read_atomic_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t *value); -int mem_ap_write_atomic_u32(struct swjdp_common *swjdp, +int mem_ap_write_atomic_u32(struct adiv5_dap *swjdp, uint32_t address, uint32_t value); /* MEM-AP memory mapped bus block transfers */ -int mem_ap_read_buf_u8(struct swjdp_common *swjdp, +int mem_ap_read_buf_u8(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address); -int mem_ap_read_buf_u16(struct swjdp_common *swjdp, +int mem_ap_read_buf_u16(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address); -int mem_ap_read_buf_u32(struct swjdp_common *swjdp, +int mem_ap_read_buf_u32(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address); -int mem_ap_write_buf_u8(struct swjdp_common *swjdp, +int mem_ap_write_buf_u8(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address); -int mem_ap_write_buf_u16(struct swjdp_common *swjdp, +int mem_ap_write_buf_u16(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address); -int mem_ap_write_buf_u32(struct swjdp_common *swjdp, +int mem_ap_write_buf_u32(struct adiv5_dap *swjdp, uint8_t *buffer, int count, uint32_t address); /* Initialisation of the debug system, power domains and registers */ -int ahbap_debugport_init(struct swjdp_common *swjdp); +int ahbap_debugport_init(struct adiv5_dap *swjdp); /* Commands for user dap access */ int dap_info_command(struct command_context *cmd_ctx, - struct swjdp_common *swjdp, int apsel); + struct adiv5_dap *swjdp, int apsel); #define DAP_COMMAND_HANDLER(name) \ - COMMAND_HELPER(name, struct swjdp_common *swjdp) + COMMAND_HELPER(name, struct adiv5_dap *swjdp) DAP_COMMAND_HANDLER(dap_baseaddr_command); DAP_COMMAND_HANDLER(dap_memaccess_command); DAP_COMMAND_HANDLER(dap_apsel_command); diff --git a/src/target/armv7a.c b/src/target/armv7a.c index fe87fee..92a373a 100644 --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -121,7 +121,7 @@ COMMAND_HANDLER(handle_dap_baseaddr_command) { struct target *target = get_current_target(CMD_CTX); struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; return CALL_COMMAND_HANDLER(dap_baseaddr_command, swjdp); } @@ -130,7 +130,7 @@ COMMAND_HANDLER(handle_dap_memaccess_command) { struct target *target = get_current_target(CMD_CTX); struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; return CALL_COMMAND_HANDLER(dap_memaccess_command, swjdp); } @@ -139,7 +139,7 @@ COMMAND_HANDLER(handle_dap_apsel_command) { struct target *target = get_current_target(CMD_CTX); struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; return CALL_COMMAND_HANDLER(dap_apsel_command, swjdp); } @@ -148,7 +148,7 @@ COMMAND_HANDLER(handle_dap_apid_command) { struct target *target = get_current_target(CMD_CTX); struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; return CALL_COMMAND_HANDLER(dap_apid_command, swjdp); } @@ -157,7 +157,7 @@ COMMAND_HANDLER(handle_dap_info_command) { struct target *target = get_current_target(CMD_CTX); struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; uint32_t apsel; switch (CMD_ARGC) { diff --git a/src/target/armv7a.h b/src/target/armv7a.h index 581813a..70a2d9e 100644 --- a/src/target/armv7a.h +++ b/src/target/armv7a.h @@ -51,7 +51,7 @@ struct armv7a_common struct reg_cache *core_cache; /* arm adp debug port */ - struct swjdp_common swjdp_info; + struct adiv5_dap swjdp_info; /* Core Debug Unit */ struct arm_dpm dpm; diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 65e03bf..5276af8 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -755,7 +755,7 @@ COMMAND_HANDLER(handle_dap_baseaddr_command) { struct target *target = get_current_target(CMD_CTX); struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; if (!is_armv7m(armv7m)) { command_print(CMD_CTX, "current target isn't an ARM7-M"); @@ -773,7 +773,7 @@ COMMAND_HANDLER(handle_dap_apid_command) { struct target *target = get_current_target(CMD_CTX); struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; if (!is_armv7m(armv7m)) { command_print(CMD_CTX, "current target isn't an ARM7-M"); @@ -787,7 +787,7 @@ COMMAND_HANDLER(handle_dap_apsel_command) { struct target *target = get_current_target(CMD_CTX); struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; if (!is_armv7m(armv7m)) { command_print(CMD_CTX, "current target isn't an ARM7-M"); @@ -801,7 +801,7 @@ COMMAND_HANDLER(handle_dap_memaccess_command) { struct target *target = get_current_target(CMD_CTX); struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; if (!is_armv7m(armv7m)) { command_print(CMD_CTX, "current target isn't an ARM7-M"); @@ -816,7 +816,7 @@ COMMAND_HANDLER(handle_dap_info_command) { struct target *target = get_current_target(CMD_CTX); struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; uint32_t apsel; if (!is_armv7m(armv7m)) { diff --git a/src/target/armv7m.h b/src/target/armv7m.h index 89c5064..5526505 100644 --- a/src/target/armv7m.h +++ b/src/target/armv7m.h @@ -106,7 +106,7 @@ struct armv7m_common struct reg_cache *core_cache; enum armv7m_mode core_mode; int exception_number; - struct swjdp_common swjdp_info; + struct adiv5_dap swjdp_info; uint32_t demcr; diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c index f4818f8..0dc7cee 100644 --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -67,7 +67,7 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, static int cortex_a8_init_debug_access(struct target *target) { struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; int retval; uint32_t dummy; @@ -103,7 +103,7 @@ static int cortex_a8_exec_opcode(struct target *target, uint32_t dscr; int retval; struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; dscr = dscr_p ? *dscr_p : 0; @@ -150,7 +150,7 @@ static int cortex_a8_read_regs_through_mem(struct target *target, uint32_t addre { int retval = ERROR_OK; struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; cortex_a8_dap_read_coreregister_u32(target, regfile, 0); cortex_a8_dap_write_coreregister_u32(target, address, 0); @@ -169,7 +169,7 @@ static int cortex_a8_dap_read_coreregister_u32(struct target *target, uint8_t reg = regnum&0xFF; uint32_t dscr = 0; struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; if (reg > 17) return retval; @@ -221,7 +221,7 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, uint8_t Rd = regnum&0xFF; uint32_t dscr; struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; LOG_DEBUG("register %i, value 0x%08" PRIx32, regnum, value); @@ -284,7 +284,7 @@ static int cortex_a8_dap_write_memap_register_u32(struct target *target, uint32_ { int retval; struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; retval = mem_ap_write_atomic_u32(swjdp, address, value); @@ -317,7 +317,7 @@ static int cortex_a8_write_dcc(struct cortex_a8_common *a8, uint32_t data) static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data, uint32_t *dscr_p) { - struct swjdp_common *swjdp = &a8->armv7a_common.swjdp_info; + struct adiv5_dap *swjdp = &a8->armv7a_common.swjdp_info; uint32_t dscr = DSCR_INSTR_COMP; int retval; @@ -344,7 +344,7 @@ static int cortex_a8_read_dcc(struct cortex_a8_common *a8, uint32_t *data, static int cortex_a8_dpm_prepare(struct arm_dpm *dpm) { struct cortex_a8_common *a8 = dpm_to_a8(dpm); - struct swjdp_common *swjdp = &a8->armv7a_common.swjdp_info; + struct adiv5_dap *swjdp = &a8->armv7a_common.swjdp_info; uint32_t dscr; int retval; @@ -562,7 +562,7 @@ static int cortex_a8_poll(struct target *target) uint32_t dscr; struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = &cortex_a8->armv7a_common; - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; enum target_state prev_target_state = target->state; uint8_t saved_apsel = dap_ap_get_select(swjdp); @@ -626,7 +626,7 @@ static int cortex_a8_halt(struct target *target) int retval = ERROR_OK; uint32_t dscr; struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; uint8_t saved_apsel = dap_ap_get_select(swjdp); dap_ap_select(swjdp, swjdp_debugap); @@ -664,7 +664,7 @@ static int cortex_a8_resume(struct target *target, int current, { struct armv7a_common *armv7a = target_to_armv7a(target); struct arm *armv4_5 = &armv7a->armv4_5_common; - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; // struct breakpoint *breakpoint = NULL; uint32_t resume_pc, dscr; @@ -788,7 +788,7 @@ static int cortex_a8_debug_entry(struct target *target) struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = target_to_armv7a(target); struct arm *armv4_5 = &armv7a->armv4_5_common; - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; struct reg *reg; LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr); @@ -1276,7 +1276,7 @@ static int cortex_a8_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; int retval = ERROR_INVALID_ARGUMENTS; /* cortex_a8 handles unaligned memory access */ @@ -1304,7 +1304,7 @@ static int cortex_a8_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; int retval = ERROR_INVALID_ARGUMENTS; // ??? dap_ap_select(swjdp, swjdp_memoryap); @@ -1386,7 +1386,7 @@ static int cortex_a8_bulk_write_memory(struct target *target, uint32_t address, } -static int cortex_a8_dcc_read(struct swjdp_common *swjdp, uint8_t *value, uint8_t *ctrl) +static int cortex_a8_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *ctrl) { #if 0 u16 dcrdr; @@ -1413,7 +1413,7 @@ static int cortex_a8_handle_target_request(void *priv) { struct target *target = priv; struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; if (!target_was_examined(target)) return ERROR_OK; @@ -1455,7 +1455,7 @@ static int cortex_a8_examine_first(struct target *target) { struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = &cortex_a8->armv7a_common; - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; int i; int retval = ERROR_OK; uint32_t didr, ctypr, ttypr, cpuid; @@ -1562,7 +1562,7 @@ static int cortex_a8_init_arch_info(struct target *target, { struct armv7a_common *armv7a = &cortex_a8->armv7a_common; struct arm *armv4_5 = &armv7a->armv4_5_common; - struct swjdp_common *swjdp = &armv7a->swjdp_info; + struct adiv5_dap *swjdp = &armv7a->swjdp_info; /* Setup struct cortex_a8_common */ cortex_a8->common_magic = CORTEX_A8_COMMON_MAGIC; diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 3178ce3..852965c 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -59,7 +59,7 @@ static void cortex_m3_enable_watchpoints(struct target *target); static int cortex_m3_store_core_reg_u32(struct target *target, enum armv7m_regtype type, uint32_t num, uint32_t value); -static int cortexm3_dap_read_coreregister_u32(struct swjdp_common *swjdp, +static int cortexm3_dap_read_coreregister_u32(struct adiv5_dap *swjdp, uint32_t *value, int regnum) { int retval; @@ -94,7 +94,7 @@ static int cortexm3_dap_read_coreregister_u32(struct swjdp_common *swjdp, return retval; } -static int cortexm3_dap_write_coreregister_u32(struct swjdp_common *swjdp, +static int cortexm3_dap_write_coreregister_u32(struct adiv5_dap *swjdp, uint32_t value, int regnum) { int retval; @@ -129,7 +129,7 @@ static int cortex_m3_write_debug_halt_mask(struct target *target, uint32_t mask_on, uint32_t mask_off) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; /* mask off status bits */ cortex_m3->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off); @@ -142,7 +142,7 @@ static int cortex_m3_write_debug_halt_mask(struct target *target, static int cortex_m3_clear_halt(struct target *target) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; /* clear step if any */ cortex_m3_write_debug_halt_mask(target, C_HALT, C_STEP); @@ -160,7 +160,7 @@ static int cortex_m3_clear_halt(struct target *target) static int cortex_m3_single_step_core(struct target *target) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; uint32_t dhcsr_save; /* backup dhcsr reg */ @@ -191,7 +191,7 @@ static int cortex_m3_endreset_event(struct target *target) uint32_t dcb_demcr; struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; - struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; struct cortex_m3_fp_comparator *fp_list = cortex_m3->fp_comparator_list; struct cortex_m3_dwt_comparator *dwt_list = cortex_m3->dwt_comparator_list; @@ -286,7 +286,7 @@ static int cortex_m3_examine_exception_reason(struct target *target) { uint32_t shcsr, except_sr, cfsr = -1, except_ar = -1; struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; int retval; mem_ap_read_u32(swjdp, NVIC_SHCSR, &shcsr); @@ -360,7 +360,7 @@ static int cortex_m3_debug_entry(struct target *target) struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; struct arm *arm = &armv7m->arm; - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; struct reg *r; LOG_DEBUG(" "); @@ -452,7 +452,7 @@ static int cortex_m3_poll(struct target *target) int retval; enum target_state prev_target_state = target->state; struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; /* Read from Debug Halting Control and Status Register */ retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); @@ -587,7 +587,7 @@ static int cortex_m3_halt(struct target *target) static int cortex_m3_soft_reset_halt(struct target *target) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; uint32_t dcb_dhcsr = 0; int retval, timeout = 0; @@ -761,7 +761,7 @@ static int cortex_m3_step(struct target *target, int current, { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; struct breakpoint *breakpoint = NULL; struct reg *pc = armv7m->arm.pc; bool bkpt_inst_found = false; @@ -826,7 +826,7 @@ static int cortex_m3_step(struct target *target, int current, static int cortex_m3_assert_reset(struct target *target) { struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; int assert_srst = 1; LOG_DEBUG("target->state: %s", @@ -1376,7 +1376,7 @@ static int cortex_m3_load_core_reg_u32(struct target *target, { int retval; struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; /* NOTE: we "know" here that the register identifiers used * in the v7m header match the Cortex-M3 Debug Core Register @@ -1440,7 +1440,7 @@ static int cortex_m3_store_core_reg_u32(struct target *target, int retval; uint32_t reg; struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; #ifdef ARMV7_GDB_HACKS /* If the LR register is being modified, make sure it will put us @@ -1518,7 +1518,7 @@ static int cortex_m3_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; int retval = ERROR_INVALID_ARGUMENTS; /* cortex_m3 handles unaligned memory access */ @@ -1543,7 +1543,7 @@ static int cortex_m3_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) { struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; int retval = ERROR_INVALID_ARGUMENTS; if (count && buffer) { @@ -1724,7 +1724,7 @@ static int cortex_m3_examine(struct target *target) uint32_t cpuid, fpcr; int i; struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - struct swjdp_common *swjdp = &cortex_m3->armv7m.swjdp_info; + struct adiv5_dap *swjdp = &cortex_m3->armv7m.swjdp_info; if ((retval = ahbap_debugport_init(swjdp)) != ERROR_OK) return retval; @@ -1773,7 +1773,7 @@ static int cortex_m3_examine(struct target *target) return ERROR_OK; } -static int cortex_m3_dcc_read(struct swjdp_common *swjdp, uint8_t *value, uint8_t *ctrl) +static int cortex_m3_dcc_read(struct adiv5_dap *swjdp, uint8_t *value, uint8_t *ctrl) { uint16_t dcrdr; @@ -1798,7 +1798,7 @@ static int cortex_m3_target_request_data(struct target *target, uint32_t size, uint8_t *buffer) { struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; uint8_t data; uint8_t ctrl; uint32_t i; @@ -1818,7 +1818,7 @@ static int cortex_m3_handle_target_request(void *priv) if (!target_was_examined(target)) return ERROR_OK; struct armv7m_common *armv7m = target_to_armv7m(target); - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; if (!target->dbg_msg_enabled) return ERROR_OK; @@ -1936,7 +1936,7 @@ COMMAND_HANDLER(handle_cortex_m3_vector_catch_command) struct target *target = get_current_target(CMD_CTX); struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; - struct swjdp_common *swjdp = &armv7m->swjdp_info; + struct adiv5_dap *swjdp = &armv7m->swjdp_info; uint32_t demcr = 0; int retval; ----------------------------------------------------------------------- Summary of changes: src/target/arm_adi_v5.c | 64 +++++++++++++++++++++++----------------------- src/target/arm_adi_v5.h | 64 ++++++++++++++++++++++------------------------ src/target/armv7a.c | 10 +++--- src/target/armv7a.h | 2 +- src/target/armv7m.c | 10 +++--- src/target/armv7m.h | 2 +- src/target/cortex_a8.c | 36 +++++++++++++------------- src/target/cortex_m3.c | 42 +++++++++++++++--------------- 8 files changed, 114 insertions(+), 116 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-03-04 17:43:22
|
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 5e78ddcea0d8303c316f687c05dfa78af27109d8 (commit) via 5fdf9535cef7e43f6e99081b6d1f6bd682184803 (commit) from 99939c3c75f3bef44d4cd176e90a6c5fe8b833da (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 5e78ddcea0d8303c316f687c05dfa78af27109d8 Author: David Brownell <dbr...@us...> Date: Wed Mar 3 21:01:16 2010 -0800 NOR: trim range in flash_driver_protect() When the beginning or end of the specified range of sectors already has the requested protection status, don't ask the flash driver to change those sectors. This will among other things turn command sequences like this into the NOPs one would expect: flash protect_check 0 flash info 0 ... reports everything as unprotected ... flash protect 0 0 1 off That speeds things up (by whatever work was just avoided). Also, with Stellaris (which can't unprotect flash at page level) this can eliminate some undesirable/false error reports. (And finishes fixing a bug currently listed in our bug database...) Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c index fc020a8..767006d 100644 --- a/src/flash/nor/core.c +++ b/src/flash/nor/core.c @@ -54,6 +54,63 @@ int flash_driver_erase(struct flash_bank *bank, int first, int last) int flash_driver_protect(struct flash_bank *bank, int set, int first, int last) { int retval; + bool updated = false; + + /* NOTE: "first == last" means protect just that sector */ + + /* callers may not supply illegal parameters ... */ + if (first < 0 || first > last || last >= bank->num_sectors) + return ERROR_FAIL; + + /* force "set" to 0/1 */ + set = !!set; + + /* + * Filter out what trivial nonsense we can, so drivers don't have to. + * + * Don't tell drivers to change to the current state... it's needless, + * and reducing the amount of work to be done (potentially to nothing) + * speeds at least some things up. + */ +scan: + for (int i = first; i < last; i++) { + struct flash_sector *sector = bank->sectors + i; + + /* Only filter requests to protect the already-protected, or + * to unprotect the already-unprotected. Changing from the + * unknown state (-1) to a known one is unwise but allowed; + * protection status is best checked first. + */ + if (sector->is_protected != set) + continue; + + /* Shrink this range of sectors from the start; don't overrun + * the end. Also shrink from the end; don't overun the start. + * + * REVISIT we could handle discontiguous regions by issuing + * more than one driver request. How much would that matter? + */ + if (i == first) { + updated = true; + first++; + } else if (i == last) { + updated = true; + last--; + } + } + + /* updating the range affects the tests in the scan loop above; so + * re-scan, to make sure we didn't miss anything. + */ + if (updated) { + updated = false; + goto scan; + } + + /* Single sector, already protected? Nothing to do! */ + if (first == last) + return ERROR_OK; + retval = bank->driver->protect(bank, set, first, last); if (retval != ERROR_OK) commit 5fdf9535cef7e43f6e99081b6d1f6bd682184803 Author: David Brownell <dbr...@us...> Date: Wed Mar 3 20:57:49 2010 -0800 NOR: invalidate cached state on target resume The NOR infrastructure caches some per-sector state, but it's not used much ... because the cache is not trustworthy. This patch addresses one part of that problem, by ensuring that state cached by NOR drivers gets invalidated once we resume the target -- since targets may then modify sectors. Now if we see sector protection or erase status marked as anything other than "unknown", we should be able to rely on that as being accurate. (That is ... if we assume the drivers initialize and update this state correctly.) Another part of that problem is that the cached state isn't much used (being unreliable, it would have been unsafe). Those issues can be addressed in later patches. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c index 2c61519..fc020a8 100644 --- a/src/flash/nor/core.c +++ b/src/flash/nor/core.c @@ -657,3 +657,34 @@ int flash_write(struct target *target, struct image *image, { return flash_write_unlock(target, image, written, erase, false); } + +/** + * Invalidates cached flash state which a target can change as it runs. + * + * @param target The target being resumed + * + * OpenOCD caches some flash state for brief periods. For example, a sector + * that is protected must be unprotected before OpenOCD tries to write it, + * Also, a sector that's not erased must be erased before it's written. + * + * As a rule, OpenOCD and target firmware can both modify the flash, so when + * a target starts running, OpenOCD needs to invalidate its cached state. + */ +void nor_resume(struct target *target) +{ + struct flash_bank *bank; + + for (bank = flash_banks; bank; bank = bank->next) { + int i; + + if (bank->target != target) + continue; + + for (i = 0; i < bank->num_sectors; i++) { + struct flash_sector *sector = bank->sectors + i; + + sector->is_erased = -1; + sector->is_protected = -1; + } + } +} diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h index b164b8d..98763b7 100644 --- a/src/flash/nor/core.h +++ b/src/flash/nor/core.h @@ -122,6 +122,10 @@ int flash_erase_address_range(struct target *target, */ int flash_write(struct target *target, struct image *image, uint32_t *written, int erase); + +/* invalidate cached state (targets may modify their own flash) */ +void nor_resume(struct target *target); + /** * Forces targets to re-examine their erase/protection state. * This routine must be called when the system may modify the status. diff --git a/src/target/target.c b/src/target/target.c index 9596302..1eb1435 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -35,6 +35,7 @@ #include <helper/time_support.h> #include <jtag/jtag.h> +#include <flash/nor/core.h> #include "target.h" #include "target_type.h" @@ -472,6 +473,14 @@ int target_resume(struct target *target, int current, uint32_t address, int hand if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK) return retval; + /* Invalidate any cached protect/erase/... flash status, since + * almost all targets will now be able modify the flash by + * themselves. We want flash drivers and infrastructure to + * be able to rely on (non-invalidated) cached state. + * + * REVISIT do the same for NAND ; maybe other flash flavors too... + */ + nor_resume(target); return retval; } ----------------------------------------------------------------------- Summary of changes: src/flash/nor/core.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/flash/nor/core.h | 4 ++ src/target/target.c | 9 +++++ 3 files changed, 101 insertions(+), 0 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-03-04 17:24:46
|
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 99939c3c75f3bef44d4cd176e90a6c5fe8b833da (commit) from 2119c0a7641d05ad8b6b8feb64d4c315716f6d3a (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 99939c3c75f3bef44d4cd176e90a6c5fe8b833da Author: David Brownell <dbr...@us...> Date: Wed Mar 3 12:59:53 2010 -0800 NOR: stellaris message tweaks Give a more accurate failure message when trying to unprotect; don't complain about pages being write protected, just say that unprotect is not supported by the hardware ... referencing the new "recover" command, which is the way to achieve that. Likewise, when trying to protect, talk about "pages" (matching hardware doc) not "sectors" (an concept that's alien to these chips). Also make the helptext for the "recover" command mention that it also erases the device. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index c9c800e..0b7c45a 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -693,8 +693,8 @@ static int stellaris_protect(struct flash_bank *bank, int set, int first, int la if (!set) { - LOG_ERROR("Can't unprotect write-protected pages."); - /* except by the "recover locked device" procedure ... */ + LOG_ERROR("Hardware doesn't suppport page-level unprotect. " + "Try the 'recover' command."); return ERROR_INVALID_ARGUMENTS; } @@ -706,7 +706,7 @@ static int stellaris_protect(struct flash_bank *bank, int set, int first, int la || (last < first) || !(last & 1) || (last >= 2 * stellaris_info->num_lockbits)) { - LOG_ERROR("Can't protect unaligned or out-of-range sectors."); + LOG_ERROR("Can't protect unaligned or out-of-range pages."); return ERROR_FLASH_SECTOR_INVALID; } @@ -1240,7 +1240,7 @@ static const struct command_registration stellaris_exec_command_handlers[] = { .handler = stellaris_handle_recover_command, .mode = COMMAND_EXEC, .usage = "bank_id", - .help = "recover locked device", + .help = "recover (and erase) locked device", }, COMMAND_REGISTRATION_DONE }; ----------------------------------------------------------------------- Summary of changes: src/flash/nor/stellaris.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: Spencer O. <nt...@us...> - 2010-03-03 11:22:55
|
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 2119c0a7641d05ad8b6b8feb64d4c315716f6d3a (commit) from 381ce4308c60c54e3a03d97e883302909b834875 (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 2119c0a7641d05ad8b6b8feb64d4c315716f6d3a Author: Spencer Oliver <nt...@us...> Date: Wed Mar 3 10:20:37 2010 +0000 STM32: Add Value Line Flash Programming Support Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/flash/nor/stm32x.c b/src/flash/nor/stm32x.c index 53fc4ea..ebdcde7 100644 --- a/src/flash/nor/stm32x.c +++ b/src/flash/nor/stm32x.c @@ -743,6 +743,21 @@ static int stm32x_probe(struct flash_bank *bank) num_pages = 256; } } + else if ((device_id & 0x7ff) == 0x420) + { + /* value line density - we have 1k pages + * 4 pages for a protection area */ + page_size = 1024; + stm32x_info->ppage_size = 4; + + /* check for early silicon */ + if (num_pages == 0xffff) + { + /* number of sectors may be incorrrect on early silicon */ + LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 128k flash"); + num_pages = 128; + } + } else { LOG_WARNING("Cannot identify target as a STM32 family."); @@ -884,6 +899,27 @@ static int stm32x_info(struct flash_bank *bank, char *buf, int buf_size) break; } } + else if ((device_id & 0x7ff) == 0x420) + { + printed = snprintf(buf, buf_size, "stm32x (Value) - Rev: "); + buf += printed; + buf_size -= printed; + + switch (device_id >> 16) + { + case 0x1000: + snprintf(buf, buf_size, "A"); + break; + + case 0x1001: + snprintf(buf, buf_size, "Z"); + break; + + default: + snprintf(buf, buf_size, "unknown"); + break; + } + } else { snprintf(buf, buf_size, "Cannot identify target as a stm32x\n"); ----------------------------------------------------------------------- Summary of changes: src/flash/nor/stm32x.c | 36 ++++++++++++++++++++++++++++++++++++ 1 files changed, 36 insertions(+), 0 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-03-03 07:55:50
|
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 381ce4308c60c54e3a03d97e883302909b834875 (commit) via 61ee632dbc4dce5f4ce6f6dac537f488595917b9 (commit) via 24b1426a728f2bac1b3828069fa13af2be6d9e94 (commit) via db6c994642f29b7d47abb4233494a606fbb65369 (commit) from d72e90ae4b070cc08799e800c111dd422ac6b1a4 (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 381ce4308c60c54e3a03d97e883302909b834875 Author: David Brownell <dbr...@us...> Date: Tue Mar 2 22:49:36 2010 -0800 ADIv5: use new DAP ops for AP read/write Make ADIv5 internals use the two new transport-neutral calls for reading and writing DP registers; and do the same for external callers. Also, bugfix some of their call sites to handle the fault returns, instead of ignoring them. Remove most of the JTAG-specific calls, using their code as the bodies of the JTAG-specific implementation for the new methods. NOTE that there's a remaining issue: mem_ap_read_buf_u32() makes calls which are JTAG-specific. A later patch will need to remove those, so JTAG-specific operations can be removed from this file, and so that SWD support will be able to properly drop in as just a transport layer to the ADIv5 infrastructure. (The way read results are posted may need some more attention in the transport-neutrality interface.) Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 2d9ea0d..c5e0dd3 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -328,8 +328,16 @@ static int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat); - dap_ap_read_reg_u32(swjdp, AP_REG_CSW, &mem_ap_csw); - dap_ap_read_reg_u32(swjdp, AP_REG_TAR, &mem_ap_tar); + retval = dap_queue_ap_read(swjdp, + AP_REG_CSW, &mem_ap_csw); + if (retval != ERROR_OK) + return retval; + + retval = dap_queue_ap_read(swjdp, + AP_REG_TAR, &mem_ap_tar); + if (retval != ERROR_OK) + return retval; + if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%" @@ -375,79 +383,6 @@ void dap_ap_select(struct swjdp_common *swjdp,uint8_t apsel) } } -/** Select the AP register bank matching bits 7:4 of ap_reg. */ -static int dap_ap_bankselect(struct swjdp_common *swjdp, uint32_t ap_reg) -{ - uint32_t select = (ap_reg & 0x000000F0); - - if (select != swjdp->ap_bank_value) - { - swjdp->ap_bank_value = select; - select |= swjdp->apsel; - return dap_queue_dp_write(swjdp, DP_SELECT, select); - } else - return ERROR_OK; -} - -/* FIXME remove dap_ap_{read,write}_reg() and dap_ap_write_reg_u32() - * ... these should become the bodies of the JTAG implementations of - * dap_queue_ap_{read,write}(), then all their current callers should - * switch over to the transport-neutral calls. - */ - -static int dap_ap_write_reg(struct swjdp_common *swjdp, - uint32_t reg_addr, uint8_t *out_value_buf) -{ - int retval; - - retval = dap_ap_bankselect(swjdp, reg_addr); - if (retval != ERROR_OK) - return retval; - - return adi_jtag_ap_write_check(swjdp, reg_addr, out_value_buf); -} - -/** - * Asynchronous (queued) AP register write. - * - * @param swjdp The DAP whose currently selected AP will be written. - * @param reg_addr Eight bit AP register address. - * @param value Word to be written at reg_addr - * - * @return ERROR_OK if the transaction was properly queued, else a fault code. - */ -int dap_ap_write_reg_u32(struct swjdp_common *swjdp, - uint32_t reg_addr, uint32_t value) -{ - uint8_t out_value_buf[4]; - - buf_set_u32(out_value_buf, 0, 32, value); - return dap_ap_write_reg(swjdp, - reg_addr, out_value_buf); -} - -/** - * Asynchronous (queued) AP register eread. - * - * @param swjdp The DAP whose currently selected AP will be read. - * @param reg_addr Eight bit AP register address. - * @param value Points to where the 32-bit (little-endian) word will be stored. - * - * @return ERROR_OK if the transaction was properly queued, else a fault code. - */ -int dap_ap_read_reg_u32(struct swjdp_common *swjdp, - uint32_t reg_addr, uint32_t *value) -{ - int retval; - - retval = dap_ap_bankselect(swjdp, reg_addr); - if (retval != ERROR_OK) - return retval; - - return adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_APACC, reg_addr, - DPAP_READ, 0, value); -} - /** * Queue transactions setting up transfer parameters for the * currently selected MEM-AP. @@ -475,7 +410,7 @@ int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar) if (csw != swjdp->ap_csw_value) { /* LOG_DEBUG("DAP: Set CSW %x",csw); */ - retval = dap_ap_write_reg_u32(swjdp, AP_REG_CSW, csw); + retval = dap_queue_ap_write(swjdp, AP_REG_CSW, csw); if (retval != ERROR_OK) return retval; swjdp->ap_csw_value = csw; @@ -483,7 +418,7 @@ int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar) if (tar != swjdp->ap_tar_value) { /* LOG_DEBUG("DAP: Set TAR %x",tar); */ - retval = dap_ap_write_reg_u32(swjdp, AP_REG_TAR, tar); + retval = dap_queue_ap_write(swjdp, AP_REG_TAR, tar); if (retval != ERROR_OK) return retval; swjdp->ap_tar_value = tar; @@ -518,7 +453,7 @@ int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, if (retval != ERROR_OK) return retval; - return dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), value); + return dap_queue_ap_read(swjdp, AP_REG_BD0 | (address & 0xC), value); } /** @@ -569,7 +504,7 @@ int mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, if (retval != ERROR_OK) return retval; - return dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), + return dap_queue_ap_write(swjdp, AP_REG_BD0 | (address & 0xC), value); } @@ -645,7 +580,10 @@ int mem_ap_write_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, for (writecount = 0; writecount < blocksize; writecount++) { - dap_ap_write_reg(swjdp, AP_REG_DRW, buffer + 4 * writecount); + retval = dap_queue_ap_write(swjdp, AP_REG_DRW, + *(uint32_t *) (buffer + 4 * writecount)); + if (retval != ERROR_OK) + break; } if (dap_run(swjdp) == ERROR_OK) @@ -725,7 +663,11 @@ static int mem_ap_write_buf_packed_u16(struct swjdp_common *swjdp, } memcpy(&outvalue, buffer, sizeof(uint32_t)); - dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue); + retval = dap_queue_ap_write(swjdp, + AP_REG_DRW, outvalue); + if (retval != ERROR_OK) + break; + if (dap_run(swjdp) != ERROR_OK) { LOG_WARNING("Block write error address " @@ -759,7 +701,10 @@ int mem_ap_write_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint16_t svalue; memcpy(&svalue, buffer, sizeof(uint16_t)); uint32_t outvalue = (uint32_t)svalue << 8 * (address & 0x3); - dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue); + retval = dap_queue_ap_write(swjdp, AP_REG_DRW, outvalue); + if (retval != ERROR_OK) + break; + retval = dap_run(swjdp); if (retval != ERROR_OK) break; @@ -822,7 +767,11 @@ static int mem_ap_write_buf_packed_u8(struct swjdp_common *swjdp, } memcpy(&outvalue, buffer, sizeof(uint32_t)); - dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue); + retval = dap_queue_ap_write(swjdp, + AP_REG_DRW, outvalue); + if (retval != ERROR_OK) + break; + if (dap_run(swjdp) != ERROR_OK) { LOG_WARNING("Block write error address " @@ -854,7 +803,10 @@ int mem_ap_write_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, { dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address); uint32_t outvalue = (uint32_t)*buffer << 8 * (address & 0x3); - dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue); + retval = dap_queue_ap_write(swjdp, AP_REG_DRW, outvalue); + if (retval != ERROR_OK) + break; + retval = dap_run(swjdp); if (retval != ERROR_OK) break; @@ -903,6 +855,13 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address); + /* FIXME remove these three calls to adi_jtag_dp_scan(), + * so this routine becomes transport-neutral. Be careful + * not to cause performance problems with JTAG; would it + * suffice to loop over dap_queue_ap_read(), or would that + * be slower when JTAG is the chosen transport? + */ + /* Scan out first read */ adi_jtag_dp_scan(swjdp, JTAG_DP_APACC, AP_REG_DRW, DPAP_READ, 0, NULL, NULL); @@ -992,7 +951,7 @@ static int mem_ap_read_buf_packed_u16(struct swjdp_common *swjdp, do { - dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue); + retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue); if (dap_run(swjdp) != ERROR_OK) { LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count); @@ -1037,7 +996,10 @@ int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, while (count > 0) { dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address); - dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue); + retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue); + if (retval != ERROR_OK) + break; + retval = dap_run(swjdp); if (retval != ERROR_OK) break; @@ -1094,7 +1056,7 @@ static int mem_ap_read_buf_packed_u8(struct swjdp_common *swjdp, do { - dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue); + retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue); if (dap_run(swjdp) != ERROR_OK) { LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count); @@ -1139,7 +1101,7 @@ int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, while (count > 0) { dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address); - dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue); + retval = dap_queue_ap_read(swjdp, AP_REG_DRW, &invalue); retval = dap_run(swjdp); if (retval != ERROR_OK) break; @@ -1199,6 +1161,7 @@ static int jtag_dp_q_write(struct swjdp_common *dap, unsigned reg, reg, DPAP_WRITE, data, NULL); } +/** Select the AP register bank matching bits 7:4 of reg. */ static int jtag_ap_q_bankselect(struct swjdp_common *dap, unsigned reg) { uint32_t select = reg & 0x000000F0; @@ -1219,17 +1182,23 @@ static int jtag_ap_q_read(struct swjdp_common *dap, unsigned reg, if (retval != ERROR_OK) return retval; - return dap_ap_read_reg_u32(dap, reg, data); + + return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_APACC, reg, + DPAP_READ, 0, data); } static int jtag_ap_q_write(struct swjdp_common *dap, unsigned reg, uint32_t data) { - int retval = jtag_ap_q_bankselect(dap, reg); + uint8_t out_value_buf[4]; + int retval = jtag_ap_q_bankselect(dap, reg); if (retval != ERROR_OK) return retval; - return dap_ap_write_reg_u32(dap, reg, data); + + buf_set_u32(out_value_buf, 0, 32, data); + + return adi_jtag_ap_write_check(dap, reg, out_value_buf); } static int jtag_ap_q_abort(struct swjdp_common *dap, uint8_t *ack) @@ -1355,8 +1324,8 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) * Should it? If the ROM address is valid, is this the right * place to scan the table and do any topology detection? */ - dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &idreg); - dap_ap_read_reg_u32(swjdp, AP_REG_BASE, &romaddr); + retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &idreg); + retval = dap_queue_ap_read(swjdp, AP_REG_BASE, &romaddr); LOG_DEBUG("MEM-AP #%d ID Register 0x%" PRIx32 ", Debug ROM Address 0x%" PRIx32, @@ -1398,8 +1367,8 @@ int dap_info_command(struct command_context *cmd_ctx, apselold = swjdp->apsel; dap_ap_select(swjdp, apsel); - dap_ap_read_reg_u32(swjdp, AP_REG_BASE, &dbgbase); - dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &apid); + retval = dap_queue_ap_read(swjdp, AP_REG_BASE, &dbgbase); + retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &apid); retval = dap_run(swjdp); if (retval != ERROR_OK) return retval; @@ -1770,7 +1739,7 @@ DAP_COMMAND_HANDLER(dap_baseaddr_command) * though they're not common for now. This should * use the ID register to verify it's a MEM-AP. */ - dap_ap_read_reg_u32(swjdp, AP_REG_BASE, &baseaddr); + retval = dap_queue_ap_read(swjdp, AP_REG_BASE, &baseaddr); retval = dap_run(swjdp); if (retval != ERROR_OK) return retval; @@ -1825,7 +1794,7 @@ DAP_COMMAND_HANDLER(dap_apsel_command) } dap_ap_select(swjdp, apsel); - dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &apid); + retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &apid); retval = dap_run(swjdp); if (retval != ERROR_OK) return retval; @@ -1859,7 +1828,7 @@ DAP_COMMAND_HANDLER(dap_apid_command) if (apselsave != apsel) dap_ap_select(swjdp, apsel); - dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &apid); + retval = dap_queue_ap_read(swjdp, AP_REG_IDR, &apid); retval = dap_run(swjdp); if (retval != ERROR_OK) return retval; diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index e71feb9..e867b85 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -350,10 +350,6 @@ void dap_ap_select(struct swjdp_common *dap,uint8_t apsel); /* Queued AP transactions */ int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar); -int dap_ap_write_reg_u32(struct swjdp_common *swjdp, - uint32_t addr, uint32_t value); -int dap_ap_read_reg_u32(struct swjdp_common *swjdp, - uint32_t addr, uint32_t *value); /* Queued MEM-AP memory mapped single word transfers */ int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t *value); diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 7aec015..3178ce3 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -72,13 +72,19 @@ static int cortexm3_dap_read_coreregister_u32(struct swjdp_common *swjdp, /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */ dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0); - dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum); + retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum); + if (retval != ERROR_OK) + return retval; /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */ dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0); - dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value); + retval = dap_queue_ap_read(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value); + if (retval != ERROR_OK) + return retval; retval = dap_run(swjdp); + if (retval != ERROR_OK) + return retval; /* restore DCB_DCRDR - this needs to be in a seperate * transaction otherwise the emulated DCC channel breaks */ @@ -101,11 +107,13 @@ static int cortexm3_dap_write_coreregister_u32(struct swjdp_common *swjdp, /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */ dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0); - dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value); + retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value); + // XXX check retval /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */ dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0); - dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR); + retval = dap_queue_ap_write(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR); + // XXX check retval retval = dap_run(swjdp); commit 61ee632dbc4dce5f4ce6f6dac537f488595917b9 Author: David Brownell <dbr...@us...> Date: Tue Mar 2 22:46:38 2010 -0800 ADIv5: use new DAP ops for DP read/write Make ADIv5 internals use the two new transport-neutral calls for reading and writing DP registers. Also, bugfix some of their call sites to handle the fault returns, instead of ignoring them. Remove the old JTAG-specific calls, using their code as the bodies of the JTAG-specific implementation for the new methods. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index daabd8b..2d9ea0d 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -350,25 +350,6 @@ static int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) * * ***************************************************************************/ -/* FIXME remove dap_dp_{read,write}_reg() ... these should become the - * bodies of the JTAG implementations of dap_queue_dp_{read,write}() and - * callers should switch over to the transport-neutral calls. - */ - -static int dap_dp_write_reg(struct swjdp_common *swjdp, - uint32_t value, uint8_t reg_addr) -{ - return adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, - reg_addr, DPAP_WRITE, value, NULL); -} - -static int dap_dp_read_reg(struct swjdp_common *swjdp, - uint32_t *value, uint8_t reg_addr) -{ - return adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, - reg_addr, DPAP_READ, 0, value); -} - /** * Select one of the APs connected to the specified DAP. The * selection is implicitly used with future AP transactions. @@ -403,7 +384,7 @@ static int dap_ap_bankselect(struct swjdp_common *swjdp, uint32_t ap_reg) { swjdp->ap_bank_value = select; select |= swjdp->apsel; - return dap_dp_write_reg(swjdp, select, DP_SELECT); + return dap_queue_dp_write(swjdp, DP_SELECT, select); } else return ERROR_OK; } @@ -1207,13 +1188,15 @@ static int jtag_idcode_q_read(struct swjdp_common *dap, static int jtag_dp_q_read(struct swjdp_common *dap, unsigned reg, uint32_t *data) { - return dap_dp_read_reg(dap, data, reg); + return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC, + reg, DPAP_READ, 0, data); } static int jtag_dp_q_write(struct swjdp_common *dap, unsigned reg, uint32_t data) { - return dap_dp_write_reg(dap, data, reg); + return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC, + reg, DPAP_WRITE, data, NULL); } static int jtag_ap_q_bankselect(struct swjdp_common *dap, unsigned reg) @@ -1307,14 +1290,27 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) dap_ap_select(swjdp, 0); /* DP initialization */ - dap_dp_read_reg(swjdp, &dummy, DP_CTRL_STAT); - dap_dp_write_reg(swjdp, SSTICKYERR, DP_CTRL_STAT); - dap_dp_read_reg(swjdp, &dummy, DP_CTRL_STAT); + + retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy); + if (retval != ERROR_OK) + return retval; + + retval = dap_queue_dp_write(swjdp, DP_CTRL_STAT, SSTICKYERR); + if (retval != ERROR_OK) + return retval; + + retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy); + if (retval != ERROR_OK) + return retval; swjdp->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ; + retval = dap_queue_dp_write(swjdp, DP_CTRL_STAT, swjdp->dp_ctrl_stat); + if (retval != ERROR_OK) + return retval; - dap_dp_write_reg(swjdp, swjdp->dp_ctrl_stat, DP_CTRL_STAT); - dap_dp_read_reg(swjdp, &ctrlstat, DP_CTRL_STAT); + retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &ctrlstat); + if (retval != ERROR_OK) + return retval; if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; @@ -1322,7 +1318,9 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10)) { LOG_DEBUG("DAP: wait CDBGPWRUPACK"); - dap_dp_read_reg(swjdp, &ctrlstat, DP_CTRL_STAT); + retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &ctrlstat); + if (retval != ERROR_OK) + return retval; if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; alive_sleep(10); @@ -1331,17 +1329,25 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10)) { LOG_DEBUG("DAP: wait CSYSPWRUPACK"); - dap_dp_read_reg(swjdp, &ctrlstat, DP_CTRL_STAT); + retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &ctrlstat); + if (retval != ERROR_OK) + return retval; if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; alive_sleep(10); } - dap_dp_read_reg(swjdp, &dummy, DP_CTRL_STAT); + retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy); + if (retval != ERROR_OK) + return retval; /* With debug power on we can activate OVERRUN checking */ swjdp->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT; - dap_dp_write_reg(swjdp, swjdp->dp_ctrl_stat, DP_CTRL_STAT); - dap_dp_read_reg(swjdp, &dummy, DP_CTRL_STAT); + retval = dap_queue_dp_write(swjdp, DP_CTRL_STAT, swjdp->dp_ctrl_stat); + if (retval != ERROR_OK) + return retval; + retval = dap_queue_dp_read(swjdp, DP_CTRL_STAT, &dummy); + if (retval != ERROR_OK) + return retval; /* * REVISIT this isn't actually *initializing* anything in an AP, commit 24b1426a728f2bac1b3828069fa13af2be6d9e94 Author: David Brownell <dbr...@us...> Date: Tue Mar 2 22:42:45 2010 -0800 ADIv5: use new dap_run() operation Make ADIv5 use one of the new transport-neutral interfaces: call dap_run(), not jtagdp_transaction_endcheck(). Also, make that old interface private; and bugfix some of its call sites to handle the fault returns, instead of ignoring them. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 735308a..daabd8b 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -213,7 +213,7 @@ static int adi_jtag_scan_inout_check_u32(struct swjdp_common *swjdp, return retval; } -int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) +static int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) { int retval; uint32_t ctrlstat; @@ -277,7 +277,7 @@ int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); - if ((retval = jtag_execute_queue()) != ERROR_OK) + if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; swjdp->ack = swjdp->ack & 0x7; } @@ -323,20 +323,20 @@ int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) | SSTICKYERR, NULL); adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); - if ((retval = jtag_execute_queue()) != ERROR_OK) + if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat); dap_ap_read_reg_u32(swjdp, AP_REG_CSW, &mem_ap_csw); dap_ap_read_reg_u32(swjdp, AP_REG_TAR, &mem_ap_tar); - if ((retval = jtag_execute_queue()) != ERROR_OK) + if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%" PRIx32, mem_ap_csw, mem_ap_tar); } - if ((retval = jtag_execute_queue()) != ERROR_OK) + if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; return ERROR_JTAG_DEVICE_ERROR; } @@ -561,7 +561,7 @@ int mem_ap_read_atomic_u32(struct swjdp_common *swjdp, uint32_t address, if (retval != ERROR_OK) return retval; - return jtagdp_transaction_endcheck(swjdp); + return dap_run(swjdp); } /** @@ -611,7 +611,7 @@ int mem_ap_write_atomic_u32(struct swjdp_common *swjdp, uint32_t address, if (retval != ERROR_OK) return retval; - return jtagdp_transaction_endcheck(swjdp); + return dap_run(swjdp); } /***************************************************************************** @@ -667,7 +667,7 @@ int mem_ap_write_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, dap_ap_write_reg(swjdp, AP_REG_DRW, buffer + 4 * writecount); } - if (jtagdp_transaction_endcheck(swjdp) == ERROR_OK) + if (dap_run(swjdp) == ERROR_OK) { wcount = wcount - blocksize; address = address + 4 * blocksize; @@ -681,6 +681,7 @@ int mem_ap_write_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, if (errorcount > 1) { LOG_WARNING("Block write error address 0x%" PRIx32 ", wcount 0x%x", address, wcount); + /* REVISIT return the *actual* fault code */ return ERROR_JTAG_DEVICE_ERROR; } } @@ -744,11 +745,12 @@ static int mem_ap_write_buf_packed_u16(struct swjdp_common *swjdp, memcpy(&outvalue, buffer, sizeof(uint32_t)); dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue); - if (jtagdp_transaction_endcheck(swjdp) != ERROR_OK) + if (dap_run(swjdp) != ERROR_OK) { LOG_WARNING("Block write error address " "0x%" PRIx32 ", count 0x%x", address, count); + /* REVISIT return *actual* fault code */ return ERROR_JTAG_DEVICE_ERROR; } } @@ -777,7 +779,10 @@ int mem_ap_write_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, memcpy(&svalue, buffer, sizeof(uint16_t)); uint32_t outvalue = (uint32_t)svalue << 8 * (address & 0x3); dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue); - retval = jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + break; + count -= 2; address += 2; buffer += 2; @@ -837,11 +842,12 @@ static int mem_ap_write_buf_packed_u8(struct swjdp_common *swjdp, memcpy(&outvalue, buffer, sizeof(uint32_t)); dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue); - if (jtagdp_transaction_endcheck(swjdp) != ERROR_OK) + if (dap_run(swjdp) != ERROR_OK) { LOG_WARNING("Block write error address " "0x%" PRIx32 ", count 0x%x", address, count); + /* REVISIT return *actual* fault code */ return ERROR_JTAG_DEVICE_ERROR; } } @@ -868,7 +874,10 @@ int mem_ap_write_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address); uint32_t outvalue = (uint32_t)*buffer << 8 * (address & 0x3); dap_ap_write_reg_u32(swjdp, AP_REG_DRW, outvalue); - retval = jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + break; + count--; address++; buffer++; @@ -933,7 +942,7 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, adi_jtag_dp_scan(swjdp, JTAG_DP_DPACC, DP_RDBUFF, DPAP_READ, 0, buffer + 4 * readcount, &swjdp->ack); - if (jtagdp_transaction_endcheck(swjdp) == ERROR_OK) + if (dap_run(swjdp) == ERROR_OK) { wcount = wcount - blocksize; address += 4 * blocksize; @@ -948,6 +957,7 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, { LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count); + /* REVISIT return the *actual* fault code */ return ERROR_JTAG_DEVICE_ERROR; } } @@ -1002,9 +1012,10 @@ static int mem_ap_read_buf_packed_u16(struct swjdp_common *swjdp, do { dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue); - if (jtagdp_transaction_endcheck(swjdp) != ERROR_OK) + if (dap_run(swjdp) != ERROR_OK) { LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count); + /* REVISIT return the *actual* fault code */ return ERROR_JTAG_DEVICE_ERROR; } @@ -1046,7 +1057,10 @@ int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, { dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address); dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue); - retval = jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + break; + if (address & 0x1) { for (i = 0; i < 2; i++) @@ -1100,9 +1114,10 @@ static int mem_ap_read_buf_packed_u8(struct swjdp_common *swjdp, do { dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue); - if (jtagdp_transaction_endcheck(swjdp) != ERROR_OK) + if (dap_run(swjdp) != ERROR_OK) { LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count); + /* REVISIT return the *actual* fault code */ return ERROR_JTAG_DEVICE_ERROR; } @@ -1144,7 +1159,10 @@ int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, { dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address); dap_ap_read_reg_u32(swjdp, AP_REG_DRW, &invalue); - retval = jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + break; + *((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3)); count--; address++; @@ -1297,7 +1315,7 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) dap_dp_write_reg(swjdp, swjdp->dp_ctrl_stat, DP_CTRL_STAT); dap_dp_read_reg(swjdp, &ctrlstat, DP_CTRL_STAT); - if ((retval = jtag_execute_queue()) != ERROR_OK) + if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; /* Check that we have debug power domains activated */ @@ -1305,7 +1323,7 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) { LOG_DEBUG("DAP: wait CDBGPWRUPACK"); dap_dp_read_reg(swjdp, &ctrlstat, DP_CTRL_STAT); - if ((retval = jtag_execute_queue()) != ERROR_OK) + if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; alive_sleep(10); } @@ -1314,7 +1332,7 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) { LOG_DEBUG("DAP: wait CSYSPWRUPACK"); dap_dp_read_reg(swjdp, &ctrlstat, DP_CTRL_STAT); - if ((retval = jtag_execute_queue()) != ERROR_OK) + if ((retval = dap_run(swjdp)) != ERROR_OK) return retval; alive_sleep(10); } @@ -1362,7 +1380,7 @@ is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0) int dap_info_command(struct command_context *cmd_ctx, struct swjdp_common *swjdp, int apsel) { - + int retval; uint32_t dbgbase, apid; int romtable_present = 0; uint8_t mem_ap; @@ -1376,7 +1394,10 @@ int dap_info_command(struct command_context *cmd_ctx, dap_ap_select(swjdp, apsel); dap_ap_read_reg_u32(swjdp, AP_REG_BASE, &dbgbase); dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &apid); - jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + return retval; + /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */ mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0)); command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid); @@ -1428,7 +1449,10 @@ int dap_info_command(struct command_context *cmd_ctx, mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFF8, &cid2); mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFFC, &cid3); mem_ap_read_u32(swjdp, (dbgbase&0xFFFFF000) | 0xFCC, &memtype); - jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + return retval; + if (!is_dap_cid_ok(cid3, cid2, cid1, cid0)) command_print(cmd_ctx, "\tCID3 0x%2.2" PRIx32 ", CID2 0x%2.2" PRIx32 @@ -1741,7 +1765,10 @@ DAP_COMMAND_HANDLER(dap_baseaddr_command) * use the ID register to verify it's a MEM-AP. */ dap_ap_read_reg_u32(swjdp, AP_REG_BASE, &baseaddr); - retval = jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + return retval; + command_print(CMD_CTX, "0x%8.8" PRIx32, baseaddr); if (apselsave != apsel) @@ -1793,7 +1820,10 @@ DAP_COMMAND_HANDLER(dap_apsel_command) dap_ap_select(swjdp, apsel); dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &apid); - retval = jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + return retval; + command_print(CMD_CTX, "ap %" PRIi32 " selected, identification register 0x%8.8" PRIx32, apsel, apid); @@ -1824,7 +1854,10 @@ DAP_COMMAND_HANDLER(dap_apid_command) dap_ap_select(swjdp, apsel); dap_ap_read_reg_u32(swjdp, AP_REG_IDR, &apid); - retval = jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + return retval; + command_print(CMD_CTX, "0x%8.8" PRIx32, apid); if (apselsave != apsel) dap_ap_select(swjdp, apselsave); diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index ec4a179..e71feb9 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -355,9 +355,6 @@ int dap_ap_write_reg_u32(struct swjdp_common *swjdp, int dap_ap_read_reg_u32(struct swjdp_common *swjdp, uint32_t addr, uint32_t *value); -/* Queued JTAG ops must be completed with jtagdp_transaction_endcheck() */ -int jtagdp_transaction_endcheck(struct swjdp_common *swjdp); - /* Queued MEM-AP memory mapped single word transfers */ int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t *value); int mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t value); diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index aecf371..7aec015 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -78,7 +78,7 @@ static int cortexm3_dap_read_coreregister_u32(struct swjdp_common *swjdp, dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0); dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value); - retval = jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); /* restore DCB_DCRDR - this needs to be in a seperate * transaction otherwise the emulated DCC channel breaks */ @@ -107,7 +107,7 @@ static int cortexm3_dap_write_coreregister_u32(struct swjdp_common *swjdp, dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0); dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR); - retval = jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); /* restore DCB_DCRDR - this needs to be in a seperate * transaction otherwise the emulated DCC channel breaks */ @@ -179,6 +179,7 @@ static int cortex_m3_single_step_core(struct target *target) static int cortex_m3_endreset_event(struct target *target) { int i; + int retval; uint32_t dcb_demcr; struct cortex_m3_common *cortex_m3 = target_to_cm3(target); struct armv7m_common *armv7m = &cortex_m3->armv7m; @@ -234,14 +235,16 @@ static int cortex_m3_endreset_event(struct target *target) target_write_u32(target, dwt_list[i].dwt_comparator_address + 8, dwt_list[i].function); } - jtagdp_transaction_endcheck(swjdp); + retval = dap_run(swjdp); + if (retval != ERROR_OK) + return retval; register_cache_invalidate(cortex_m3->armv7m.core_cache); /* make sure we have latest dhcsr flags */ mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr); - return ERROR_OK; + return retval; } static int cortex_m3_examine_debug_reason(struct target *target) @@ -276,6 +279,7 @@ static int cortex_m3_examine_exception_reason(struct target *target) uint32_t shcsr, except_sr, cfsr = -1, except_ar = -1; struct armv7m_common *armv7m = target_to_armv7m(target); struct swjdp_common *swjdp = &armv7m->swjdp_info; + int retval; mem_ap_read_u32(swjdp, NVIC_SHCSR, &shcsr); switch (armv7m->exception_number) @@ -313,10 +317,13 @@ static int cortex_m3_examine_exception_reason(struct target *target) except_sr = 0; break; } - jtagdp_transaction_endcheck(swjdp); - LOG_DEBUG("%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32 ", CFSR 0x%" PRIx32 ", AR 0x%" PRIx32 "", armv7m_exception_string(armv7m->exception_number), \ - shcsr, except_sr, cfsr, except_ar); - return ERROR_OK; + retval = dap_run(swjdp); + if (retval == ERROR_OK) + LOG_DEBUG("%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32 + ", CFSR 0x%" PRIx32 ", AR 0x%" PRIx32, + armv7m_exception_string(armv7m->exception_number), + shcsr, except_sr, cfsr, except_ar); + return retval; } /* PSP is used in some thread modes */ commit db6c994642f29b7d47abb4233494a606fbb65369 Author: David Brownell <dbr...@us...> Date: Tue Mar 2 22:41:59 2010 -0800 ARM: start abstracting ADIv5 transports (JTAG/SWD) To support both JTAG and SWD, ADIv5 needs DAP operations which are transport-neutral, instead being of JTAG-specific. This patch: - Defines such a transport-neutral interface, abstracting access to DP and AP registers through a conceptual queue of operations. - Builds the first implementation of such a transport with the existing JTAG-specific code. In contrast to the current JTAG-only interface, the interface adds support for two previously-missing (and unused) DAP operations: - aborting the current AP transaction (untested); - reading the IDCODE register (tested) ... required for SWD init. The choice of transports may be fixed at the chip, board, or JTAG/SWD adapter level. Or if all the relevant hardware supports both transport options, the choice may be made at runtime, This patch provides basic infrastructure to support whichever choice is made. The current "JTAG-only" transport choice policy will necessarily continue for now, until SWD support becomes available in OpenOCD. Later patches start phasing out JTAG-specific calls in favor of transport-neutral calls. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 115ccf1..735308a 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -350,6 +350,11 @@ int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) * * ***************************************************************************/ +/* FIXME remove dap_dp_{read,write}_reg() ... these should become the + * bodies of the JTAG implementations of dap_queue_dp_{read,write}() and + * callers should switch over to the transport-neutral calls. + */ + static int dap_dp_write_reg(struct swjdp_common *swjdp, uint32_t value, uint8_t reg_addr) { @@ -403,6 +408,12 @@ static int dap_ap_bankselect(struct swjdp_common *swjdp, uint32_t ap_reg) return ERROR_OK; } +/* FIXME remove dap_ap_{read,write}_reg() and dap_ap_write_reg_u32() + * ... these should become the bodies of the JTAG implementations of + * dap_queue_ap_{read,write}(), then all their current callers should + * switch over to the transport-neutral calls. + */ + static int dap_ap_write_reg(struct swjdp_common *swjdp, uint32_t reg_addr, uint8_t *out_value_buf) { @@ -1143,6 +1154,107 @@ int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, return retval; } +/*--------------------------------------------------------------------------*/ + +static int jtag_idcode_q_read(struct swjdp_common *dap, + uint8_t *ack, uint32_t *data) +{ + struct arm_jtag *jtag_info = dap->jtag_info; + int retval; + struct scan_field fields[1]; + + jtag_set_end_state(TAP_IDLE); + + /* This is a standard JTAG operation -- no DAP tweakage */ + retval = arm_jtag_set_instr(jtag_info, JTAG_DP_IDCODE, NULL); + if (retval != ERROR_OK) + return retval; + + fields[0].tap = jtag_info->tap; + fields[0].num_bits = 32; + fields[0].out_value = NULL; + fields[0].in_value = (void *) data; + + jtag_add_dr_scan(1, fields, jtag_get_end_state()); + retval = jtag_get_error(); + if (retval != ERROR_OK) + return retval; + + jtag_add_callback(arm_le_to_h_u32, + (jtag_callback_data_t) data); + + return retval; +} + +static int jtag_dp_q_read(struct swjdp_common *dap, unsigned reg, + uint32_t *data) +{ + return dap_dp_read_reg(dap, data, reg); +} + +static int jtag_dp_q_write(struct swjdp_common *dap, unsigned reg, + uint32_t data) +{ + return dap_dp_write_reg(dap, data, reg); +} + +static int jtag_ap_q_bankselect(struct swjdp_common *dap, unsigned reg) +{ + uint32_t select = reg & 0x000000F0; + + if (select == dap->ap_bank_value) + return ERROR_OK; + dap->ap_bank_value = select; + + select |= dap->apsel; + + return jtag_dp_q_write(dap, DP_SELECT, select); +} + +static int jtag_ap_q_read(struct swjdp_common *dap, unsigned reg, + uint32_t *data) +{ + int retval = jtag_ap_q_bankselect(dap, reg); + + if (retval != ERROR_OK) + return retval; + return dap_ap_read_reg_u32(dap, reg, data); +} + +static int jtag_ap_q_write(struct swjdp_common *dap, unsigned reg, + uint32_t data) +{ + int retval = jtag_ap_q_bankselect(dap, reg); + + if (retval != ERROR_OK) + return retval; + return dap_ap_write_reg_u32(dap, reg, data); +} + +static int jtag_ap_q_abort(struct swjdp_common *dap, uint8_t *ack) +{ + /* for JTAG, this is the only valid ABORT register operation */ + return adi_jtag_dp_scan_u32(dap, JTAG_DP_ABORT, + 0, DPAP_WRITE, 1, NULL, ack); +} + +static int jtag_dp_run(struct swjdp_common *dap) +{ + return jtagdp_transaction_endcheck(dap); +} + +static const struct dap_ops jtag_dp_ops = { + .queue_idcode_read = jtag_idcode_q_read, + .queue_dp_read = jtag_dp_q_read, + .queue_dp_write = jtag_dp_q_write, + .queue_ap_read = jtag_ap_q_read, + .queue_ap_write = jtag_ap_q_write, + .queue_ap_abort = jtag_ap_q_abort, + .run = jtag_dp_run, +}; + +/*--------------------------------------------------------------------------*/ + /** * Initialize a DAP. This sets up the power domains, prepares the DP * for further use, and arranges to use AP #0 for all AP operations @@ -1164,6 +1276,9 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) LOG_DEBUG(" "); + /* JTAG-DP or SWJ-DP, in JTAG mode */ + swjdp->ops = &jtag_dp_ops; + /* Default MEM-AP setup. * * REVISIT AP #0 may be an inappropriate default for this. diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 5c5ca4f..ec4a179 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -124,10 +124,22 @@ * transport agent; and at least one Access Port (AP), controlling * resource access. Most common is a MEM-AP, for memory access. * + * There are two basic DP transports: JTAG, and ARM's low pin-count SWD. + * Accordingly, this interface is responsible for hiding the transport + * differences so upper layer code can largely ignore them. + * + * When the chip is implemented with JTAG-DP or SW-DP, the transport is + * fixed as JTAG or SWD, respectively. Chips incorporating SWJ-DP permit + * a choice made at board design time (by only using the SWD pins), or + * as part of setting up a debug session (if all the dual-role JTAG/SWD + * signals are available). + * * @todo Rename "swjdp_common" as "dap". Use of SWJ-DP is optional! */ struct swjdp_common { + const struct dap_ops *ops; + struct arm_jtag *jtag_info; /* Control config */ uint32_t dp_ctrl_stat; @@ -175,6 +187,157 @@ struct swjdp_common }; +/** + * Transport-neutral representation of queued DAP transactions, supporting + * both JTAG and SWD transports. All submitted transactions are logically + * queued, until the queue is executed by run(). Some implementations might + * execute transactions as soon as they're submitted, but no status is made + * availablue until run(). + */ +struct dap_ops { + /** If the DAP transport isn't SWD, it must be JTAG. Upper level + * code may need to care about the difference in some cases. + */ + bool is_swd; + + /** Reads the DAP's IDCODe register. */ + int (*queue_idcode_read)(struct swjdp_common *dap, + uint8_t *ack, uint32_t *data); + + /** DP register read. */ + int (*queue_dp_read)(struct swjdp_common *dap, unsigned reg, + uint32_t *data); + /** DP register write. */ + int (*queue_dp_write)(struct swjdp_common *dap, unsigned reg, + uint32_t data); + + /** AP register read. */ + int (*queue_ap_read)(struct swjdp_common *dap, unsigned reg, + uint32_t *data); + /** AP register write. */ + int (*queue_ap_write)(struct swjdp_common *dap, unsigned reg, + uint32_t data); + /** AP operation abort. */ + int (*queue_ap_abort)(struct swjdp_common *dap, uint8_t *ack); + + /** Executes all queued DAP operations. */ + int (*run)(struct swjdp_common *dap); +}; + +/** + * Queue an IDCODE register read. This is primarily useful for SWD + * transports, where it is required as part of link initialization. + * (For JTAG, this register is read as part of scan chain setup.) + * + * @param dap The DAP used for reading. + * @param ack Pointer to where transaction status will be stored. + * @param data Pointer saying where to store the IDCODE value. + * + * @return ERROR_OK for success, else a fault code. + */ +static inline int dap_queue_idcode_read(struct swjdp_common *dap, + uint8_t *ack, uint32_t *data) +{ + return dap->ops->queue_idcode_read(dap, ack, data); +} + +/** + * Queue a DP register read. + * Note that not all DP registers are readable; also, that JTAG and SWD + * have slight differences in DP register support. + * + * @param dap The DAP used for reading. + * @param reg The two-bit number of the DP register being read. + * @param data Pointer saying where to store the register's value + * (in host endianness). + * + * @return ERROR_OK for success, else a fault code. + */ +static inline int dap_queue_dp_read(struct swjdp_common *dap, + unsigned reg, uint32_t *data) +{ + return dap->ops->queue_dp_read(dap, reg, data); +} + +/** + * Queue a DP register write. + * Note that not all DP registers are writable; also, that JTAG and SWD + * have slight differences in DP register support. + * + * @param dap The DAP used for writing. + * @param reg The two-bit number of the DP register being written. + * @param data Value being written (host endianness) + * + * @return ERROR_OK for success, else a fault code. + */ +static inline int dap_queue_dp_write(struct swjdp_common *dap, + unsigned reg, uint32_t data) +{ + return dap->ops->queue_dp_write(dap, reg, data); +} + +/** + * Queue an AP register read. + * + * @param dap The DAP used for reading. + * @param reg The number of the AP register being read. + * @param data Pointer saying where to store the register's value + * (in host endianness). + * + * @return ERROR_OK for success, else a fault code. + */ +static inline int dap_queue_ap_read(struct swjdp_common *dap, + unsigned reg, uint32_t *data) +{ + return dap->ops->queue_ap_read(dap, reg, data); +} + +/** + * Queue an AP register write. + * + * @param dap The DAP used for writing. + * @param reg The number of the AP register being written. + * @param data Value being written (host endianness) + * + * @return ERROR_OK for success, else a fault code. + */ +static inline int dap_queue_ap_write(struct swjdp_common *dap, + unsigned reg, uint32_t data) +{ + return dap->ops->queue_ap_write(dap, reg, data); +} + +/** + * Queue an AP abort operation. The current AP transaction is aborted, + * including any update of the transaction counter. The AP is left in + * an unknown state (so it must be re-initialized). For use only after + * the AP has reported WAIT status for an extended period. + * + * @param dap The DAP used for writing. + * @param ack Pointer to where transaction status will be stored. + * + * @return ERROR_OK for success, else a fault code. + */ +static inline int dap_queue_ap_abort(struct swjdp_common *dap, uint8_t *ack) +{ + return dap->ops->queue_ap_abort(dap, ack); +} + +/** + * Perform all queued DAP operations, and clear any errors posted in the + * CTRL_STAT register when they are done. Note that if more than one AP + * operation will be queued, one of the first operations in the queue + * should probably enable CORUNDETECT in the CTRL/STAT register. + * + * @param dap The DAP used. + * + * @return ERROR_OK for success, else a fault code. + */ +static inline int dap_run(struct swjdp_common *dap) +{ + return dap->ops->run(dap); +} + /** Accessor for currently selected DAP-AP number (0..255) */ static inline uint8_t dap_ap_get_select(struct swjdp_common *swjdp) { ----------------------------------------------------------------------- Summary of changes: src/target/arm_adi_v5.c | 401 +++++++++++++++++++++++++++++++---------------- src/target/arm_adi_v5.h | 170 +++++++++++++++++++- src/target/cortex_m3.c | 39 +++-- 3 files changed, 452 insertions(+), 158 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-03-03 00:45:50
|
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 d72e90ae4b070cc08799e800c111dd422ac6b1a4 (commit) from 53b3d4dd53eebbf03f481dc59e4bc0259911864a (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 d72e90ae4b070cc08799e800c111dd422ac6b1a4 Author: David Brownell <dbr...@us...> Date: Tue Mar 2 15:45:12 2010 -0800 target_resume() doxygen Add doxygen for target_resume() ... referencing the still-unresolved confusion about what the "debug_execution" parameter means (not all CPU support code acts the same). The 'handle_breakpoints" param seems to have resolved the main issue with its semantics, but it wasn't part of the function spec before. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/target.c b/src/target/target.c index 2522408..9596302 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -424,6 +424,36 @@ int target_halt(struct target *target) return ERROR_OK; } +/** + * Make the target (re)start executing using its saved execution + * context (possibly with some modifications). + * + * @param target Which target should start executing. + * @param current True to use the target's saved program counter instead + * of the address parameter + * @param address Optionally used as the program counter. + * @param handle_breakpoints True iff breakpoints at the resumption PC + * should be skipped. (For example, maybe execution was stopped by + * such a breakpoint, in which case it would be counterprodutive to + * let it re-trigger. + * @param debug_execution False if all working areas allocated by OpenOCD + * should be released and/or restored to their original contents. + * (This would for example be true to run some downloaded "helper" + * algorithm code, which resides in one such working buffer and uses + * another for data storage.) + * + * @todo Resolve the ambiguity about what the "debug_execution" flag + * signifies. For example, Target implementations don't agree on how + * it relates to invalidation of the register cache, or to whether + * breakpoints and watchpoints should be enabled. (It would seem wrong + * to enable breakpoints when running downloaded "helper" algorithms + * (debug_execution true), since the breakpoints would be set to match + * target firmware being debugged, not the helper algorithm.... and + * enabling them could cause such helpers to malfunction (for example, + * by overwriting data with a breakpoint instruction. On the other + * hand the infrastructure for running such helpers might use this + * procedure but rely on hardware breakpoint to detect termination.) + */ int target_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution) { int retval; @@ -435,9 +465,9 @@ int target_resume(struct target *target, int current, uint32_t address, int hand return ERROR_FAIL; } - /* note that resume *must* be asynchronous. The CPU can halt before we poll. The CPU can - * even halt at the current PC as a result of a software breakpoint being inserted by (a bug?) - * the application. + /* note that resume *must* be asynchronous. The CPU can halt before + * we poll. The CPU can even halt at the current PC as a result of + * a software breakpoint being inserted by (a bug?) the application. */ if ((retval = target->type->resume(target, current, address, handle_breakpoints, debug_execution)) != ERROR_OK) return retval; ----------------------------------------------------------------------- Summary of changes: src/target/target.c | 36 +++++++++++++++++++++++++++++++++--- 1 files changed, 33 insertions(+), 3 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-03-03 00:06:48
|
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 53b3d4dd53eebbf03f481dc59e4bc0259911864a (commit) from 5b311865788009445a1457f62204899a4aa1c7b3 (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 53b3d4dd53eebbf03f481dc59e4bc0259911864a Author: David Brownell <dbr...@us...> Date: Tue Mar 2 15:00:14 2010 -0800 LPC1768 updates, IAR board support Fix some issues with the generic LPC1768 config file: - Handle the post-reset clock config: 4 MHz internal RC, no PLL. This affects flash and JTAG clocking. - Remove JTAG adapter config; they don't all support trst_and_srst - Remove the rest of the bogus "reset-init" event handler. - Allow explicit CCLK configuration, instead of assuming 12 MHz; some boards will use 100 Mhz (or the post-reset 4 MHz). - Simplify: rely on defaults for endianness and IR-Capture value - Update some comments too Build on those fixes to make a trivial config for the IAR LPC1768 kickstart board (by Olimex) start working. Also, add doxygen to the lpc2000 flash driver, primarily to note a configuration problem with driver: it wrongly assumes the core clock rate never changes. Configs that are safe for updating flash after "reset halt" will thus often be unsafe later ... e.g. for LPC1768, after switching to use PLL0 at 100 MHz. Signed-off-by: David Brownell <dbr...@us...> diff --git a/NEWS b/NEWS index 56c697f..4fef5b2 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,7 @@ Flash Layer: Board, Target, and Interface Configuration Scripts: + Support IAR LPC1768 kickstart board (by Olimex) Core Jim/TCL Scripting: diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c index 6674f17..438ab54 100644 --- a/src/flash/nor/lpc2000.c +++ b/src/flash/nor/lpc2000.c @@ -33,7 +33,15 @@ #include <target/armv7m.h> -/* flash programming support for NXP LPC17xx and LPC2xxx devices +/** + * @file + * flash programming support for NXP LPC17xx and LPC2xxx devices. + * + * @todo Provide a way to update CCLK after declaring the flash bank. + * The value which is correct after chip reset will rarely still work + * right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz). + */ +/* * currently supported devices: * variant 1 (lpc2000_v1): * - 2104 | 5 | 6 diff --git a/tcl/board/iar_lpc1768.cfg b/tcl/board/iar_lpc1768.cfg new file mode 100644 index 0000000..b8fd026 --- /dev/null +++ b/tcl/board/iar_lpc1768.cfg @@ -0,0 +1,17 @@ +# Board from IAR KickStart Kit for LPC1768 +# See www.iar.com and also +# http://www.olimex.com/dev/lpc-1766stk.html +# + +source [find target/lpc1768.cfg] + +# The chip has just been reset. +# +$_TARGETNAME configure -event reset-init { + # FIXME update the core clock to run at 100 MHz; + # and update JTAG clocking similarly; then + # make CCLK match, + + flash probe 0 +} + diff --git a/tcl/target/lpc1768.cfg b/tcl/target/lpc1768.cfg index f0093ad..182fb89 100644 --- a/tcl/target/lpc1768.cfg +++ b/tcl/target/lpc1768.cfg @@ -1,4 +1,4 @@ -# NXP LPC1768 Cortex-M3 with 512kB Flash and 32kB+32kB Local On-Chip SRAM, clocked with 4MHz internal RC oscillator +# NXP LPC1768 Cortex-M3 with 512kB Flash and 32kB+32kB Local On-Chip SRAM, if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME @@ -6,12 +6,18 @@ if { [info exists CHIPNAME] } { set _CHIPNAME lpc1768 } -if { [info exists ENDIAN] } { - set _ENDIAN $ENDIAN +# After reset the chip is clocked by the ~4MHz internal RC oscillator. +# When board-specific code (reset-init handler or device firmware) +# configures another oscillator and/or PLL0, set CCLK to match; if +# you don't, then flash erase and write operations may misbehave. +# (The ROM code doing those updates cares about core clock speed...) +# +# CCLK is the core clock frequency in KHz +if { [info exists CCLK ] } { + set _CCLK $CCLK } else { - set _ENDIAN little + set _CCLK 4000 } - if { [info exists CPUTAPID ] } { set _CPUTAPID $CPUTAPID } else { @@ -23,29 +29,25 @@ jtag_nsrst_delay 200 jtag_ntrst_delay 200 # LPC2000 & LPC1700 -> SRST causes TRST -reset_config trst_and_srst srst_pulls_trst +reset_config srst_pulls_trst -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME - -# LPC1768 has 32kB of SRAM on its main system bus (so-called Local On-Chip SRAM) -$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size 0x8000 -work-area-backup 0 +target create $_TARGETNAME cortex_m3 -chain-position $_TARGETNAME -# REVISIT is there any good reason to have this reset-init event handler?? -# Normally they should set up (board-specific) clocking then probe the flash... -$_TARGETNAME configure -event reset-init { - # Force NVIC.VTOR to point to flash at 0 ... - # WHY? This is it's reset value; we run right after reset!! - mwb 0xE000ED08 0x00 -} - -# LPC1768 has 512kB of user-available FLASH (bootloader is located in separate dedicated region). -# flash bank lpc1700 <base> <size> 0 0 <target#> <variant> <cclk> [calc_checksum] +# LPC1768 has 32kB of SRAM In the ARMv7-M "Code" area (at 0x10000000) +# and 32K more on AHB, in the ARMv7-M "SRAM" area, (at 0x2007c000). +$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size 0x8000 +# LPC1768 has 512kB of flash memory, managed by ROM code (including a +# boot loader which verifies the flash exception table's checksum). set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME lpc2000 0x0 0x80000 0 0 $_TARGETNAME lpc1700 12000 calc_checksum - -# 4MHz / 6 = 666kHz, so use 500 -jtag_khz 500 +flash bank $_FLASHNAME lpc2000 0x0 0x80000 0 0 $_TARGETNAME \ + lpc1700 $_CCLK calc_checksum + +# JTAG clock should be CCLK/6 (unless using adaptive clocking) +# CCLK is 4 MHz after reset, and until board-specific code (like +# a reset-init handler) speeds it up. +jtag_rclk [ expr 4000 / 6 ] +$_TARGETNAME configure -event reset-start { jtag_rclk [ expr 4000 / 6] } ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + src/flash/nor/lpc2000.c | 10 +++++++- tcl/board/iar_lpc1768.cfg | 17 ++++++++++++++ tcl/target/lpc1768.cfg | 52 +++++++++++++++++++++++--------------------- 4 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 tcl/board/iar_lpc1768.cfg hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-03-02 18:42:33
|
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 5b311865788009445a1457f62204899a4aa1c7b3 (commit) from cb72b7a270c7be60c1ec2ee47282156397bea846 (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 5b311865788009445a1457f62204899a4aa1c7b3 Author: David Brownell <dbr...@us...> Date: Tue Mar 2 09:39:36 2010 -0800 ADIv5: use right ID for Cortex-M3 ETM Correct a mistake made copying the ID of the Cortex-M3 ETM module from the TRM, so that "dap info" on a CM3 with an ETM will now correctly describe ROM table entries for such modules. (They are included on LPC17xx and some other cores.) Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 6be60af..115ccf1 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -1530,10 +1530,6 @@ int dap_info_command(struct command_context *cmd_ctx, type = "TI DAPCTL"; full = ""; break; - case 0x4e0: - type = "Cortex-M3 ETM"; - full = "(Embedded Trace)"; - break; case 0x906: type = "Coresight CTI"; full = "(Cross Trigger)"; @@ -1566,6 +1562,10 @@ int dap_info_command(struct command_context *cmd_ctx, type = "Cortex-M3 TPIU"; full = "(Trace Port Interface Unit)"; break; + case 0x924: + type = "Cortex-M3 ETM"; + full = "(Embedded Trace)"; + break; case 0xc08: type = "Cortex-A8 Debug"; full = "(Debug Unit)"; ----------------------------------------------------------------------- Summary of changes: src/target/arm_adi_v5.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-03-01 19:40:20
|
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 cb72b7a270c7be60c1ec2ee47282156397bea846 (commit) from b1c00e5a4e038068dce4512c5a2eb3735990b880 (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 cb72b7a270c7be60c1ec2ee47282156397bea846 Author: David Brownell <dbr...@us...> Date: Mon Mar 1 10:39:57 2010 -0800 arm_semihosting buildfix The recent "add armv7m semihosting support" patch introduced two build errors: arm_semihosting.c: In function âdo_semihostingâ: arm_semihosting.c:71: error: âspsrâ may be used uninitialized in this function arm_semihosting.c:71: error: âlrâ may be used uninitialized in this function This fixes those build errors. The behavior is, however, untested. (Also, note the two new REVISIT comments.) Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c index 2f50a4a..a247cc8 100644 --- a/src/target/arm_semihosting.c +++ b/src/target/arm_semihosting.c @@ -68,16 +68,9 @@ static int do_semihosting(struct target *target) struct arm *arm = target_to_arm(target); uint32_t r0 = buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32); uint32_t r1 = buf_get_u32(arm->core_cache->reg_list[1].value, 0, 32); - uint32_t lr, spsr; uint8_t params[16]; int retval, result; - if (is_arm7_9(target_to_arm7_9(target))) - { - lr = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, ARM_MODE_SVC, 14).value, 0, 32); - spsr = buf_get_u32(arm->spsr->value, 0, 32);; - } - /* * TODO: lots of security issues are not considered yet, such as: * - no validation on target provided file descriptors @@ -396,22 +389,35 @@ static int do_semihosting(struct target *target) /* resume execution to the original mode */ + /* REVISIT this looks wrong ... ARM11 and Cortex-A8 + * should work this way at least sometimes. + */ if (is_arm7_9(target_to_arm7_9(target))) { + uint32_t spsr; + /* return value in R0 */ buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, result); arm->core_cache->reg_list[0].dirty = 1; /* LR --> PC */ - buf_set_u32(arm->core_cache->reg_list[15].value, 0, 32, lr); + buf_set_u32(arm->core_cache->reg_list[15].value, 0, 32, + buf_get_u32(arm_reg_current(arm,14)->value, 0, 32)); arm->core_cache->reg_list[15].dirty = 1; /* saved PSR --> current PSR */ + spsr = buf_get_u32(arm->spsr->value, 0, 32); + + /* REVISIT should this be arm_set_cpsr(arm, spsr) + * instead of a partially unrolled version? + */ + buf_set_u32(arm->cpsr->value, 0, 32, spsr); arm->cpsr->dirty = 1; arm->core_mode = spsr & 0x1f; if (spsr & 0x20) arm->core_state = ARM_STATE_THUMB; + } else { ----------------------------------------------------------------------- Summary of changes: src/target/arm_semihosting.c | 22 ++++++++++++++-------- 1 files changed, 14 insertions(+), 8 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: Øyvind H. <go...@us...> - 2010-03-01 15:40:28
|
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 b1c00e5a4e038068dce4512c5a2eb3735990b880 (commit) from 27401e4c80b137f599954ac521387b247002770c (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 b1c00e5a4e038068dce4512c5a2eb3735990b880 Author: Ãyvind Harboe <oyv...@zy...> Date: Mon Mar 1 15:39:41 2010 +0100 zy1000: faster jtag_add_ir_scan() Faster and simpler. Signed-off-by: Ãyvind Harboe <oyv...@zy...> diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index 6465aaa..c5bc0ff 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -608,15 +608,9 @@ int interface_jtag_add_ir_scan(int num_fields, const struct scan_field *fields, if (!found) { /* if a device isn't listed, set it to BYPASS */ - uint8_t ones[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; - - struct scan_field tmp; - memset(&tmp, 0, sizeof(tmp)); - tmp.out_value = ones; - tmp.num_bits = scan_size; - scanFields(1, &tmp, TAP_IRSHIFT, pause); - /* update device information */ - buf_cpy(tmp.out_value, tap->cur_instr, scan_size); + assert(scan_size <= 32); + shiftValueInner(TAP_IRSHIFT, pause?TAP_IRPAUSE:TAP_IRSHIFT, scan_size, 0xffffffff); + tap->bypass = 1; } } ----------------------------------------------------------------------- Summary of changes: src/jtag/zy1000/zy1000.c | 12 +++--------- 1 files changed, 3 insertions(+), 9 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: Øyvind H. <go...@us...> - 2010-03-01 15:25:04
|
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 27401e4c80b137f599954ac521387b247002770c (commit) from afbf92766348a32a700d62a29b9a6c92537b9271 (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 27401e4c80b137f599954ac521387b247002770c Author: Ãyvind Harboe <oyv...@zy...> Date: Mon Mar 1 15:22:10 2010 +0100 zy1000: arm11 load is now faster 290kBytes/s @ 8MHz, no need to inline jtag_tap_next_enabled(). Signed-off-by: Ãyvind Harboe <oyv...@zy...> diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index b730b72..6465aaa 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -888,57 +888,86 @@ int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opc * with unaligned uint32_t * pointers... */ const uint8_t *t = (const uint8_t *)data; - while (count--) - { - values[0] = *t++; - values[0] |= (*t++<<8); - values[0] |= (*t++<<16); - values[0] |= (*t++<<24); - if (count > 0) + /* bypass bits before and after */ + int pre_bits = 0; + int post_bits = 0; + + bool found = false; + struct jtag_tap *cur_tap, *nextTap; + for (cur_tap = jtag_tap_next_enabled(NULL); cur_tap!= NULL; cur_tap = nextTap) + { + nextTap = jtag_tap_next_enabled(cur_tap); + if (cur_tap == tap) { - jtag_add_dr_out(tap, - 2, - bits, - values, - TAP_DRPAUSE); + found = true; + } else + { + if (found) + { + post_bits++; + } else + { + pre_bits++; + } + } + } + + post_bits+=2; + + + while (--count > 0) + { + shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, pre_bits, 0); + + uint32_t value; + value = *t++; + value |= (*t++<<8); + value |= (*t++<<16); + value |= (*t++<<24); + + shiftValueInner(TAP_DRSHIFT, TAP_DRSHIFT, 32, value); + shiftValueInner(TAP_DRSHIFT, TAP_DRPAUSE, post_bits, 0); #if 1 - /* copy & paste from arm11_dbgtap.c */ - //TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT - - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); + /* copy & paste from arm11_dbgtap.c */ + //TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT + + waitIdle(); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + /* we don't have to wait for the queue to empty here. waitIdle(); */ + ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); #else - static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] = - { - TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT - }; + static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] = + { + TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT + }; - jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), - arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay); + jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), + arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay); #endif - } else - { - /* This will happen on the last iteration updating the current tap state - * so we don't have to track it during the common code path */ - jtag_add_dr_out(tap, - 2, - bits, - values, - TAP_IDLE); - } } + values[0] = *t++; + values[0] |= (*t++<<8); + values[0] |= (*t++<<16); + values[0] |= (*t++<<24); + + /* This will happen on the last iteration updating the current tap state + * so we don't have to track it during the common code path */ + jtag_add_dr_out(tap, + 2, + bits, + values, + TAP_IDLE); + return jtag_execute_queue(); #endif } ----------------------------------------------------------------------- Summary of changes: src/jtag/zy1000/zy1000.c | 113 +++++++++++++++++++++++++++++----------------- 1 files changed, 71 insertions(+), 42 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: Øyvind H. <go...@us...> - 2010-03-01 13:34:13
|
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 afbf92766348a32a700d62a29b9a6c92537b9271 (commit) via 761d4555b8f8c8eb2b899dee16584656a43b6444 (commit) from 409e23e39b955d92c8e879143d2b979b7de799e9 (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 afbf92766348a32a700d62a29b9a6c92537b9271 Author: Ãyvind Harboe <oyv...@zy...> Date: Mon Mar 1 08:25:57 2010 +0100 zy1000: add jtag_add_tms_seq support Signed-off-by: Ãyvind Harboe <oyv...@zy...> diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index e21104c..b730b72 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007-2009 by Ãyvind Harboe * + * Copyright (C) 2007-2010 by Ãyvind Harboe * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -763,18 +763,52 @@ int interface_jtag_add_sleep(uint32_t us) return ERROR_OK; } +int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state) +{ + /*wait for the fifo to be empty*/ + waitIdle(); + + for (unsigned i = 0; i < num_bits; i++) + { + int tms; + + if (((seq[i/8] >> (i % 8)) & 1) == 0) + { + tms = 0; + } + else + { + tms = 1; + } + + waitIdle(); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms); + } + + waitIdle(); + if (state != TAP_INVALID) + { + ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, state); + } else + { + /* this would be normal if we are switching to SWD mode */ + } + return ERROR_OK; +} + int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) { int state_count; int tms = 0; - /*wait for the fifo to be empty*/ - waitIdle(); - state_count = 0; tap_state_t cur_state = cmd_queue_cur_state; + uint8_t seq[16]; + memset(seq, 0, sizeof(seq)); + assert(num_states < (sizeof(seq) * 8)); + while (num_states) { if (tap_state_transition(cur_state, false) == path[state_count]) @@ -791,28 +825,14 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) exit(-1); } - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, tms); + seq[state_count/8] = seq[state_count/8] | (tms << (state_count % 8)); cur_state = path[state_count]; state_count++; num_states--; } - waitIdle(); - ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, cur_state); - return ERROR_OK; -} - -int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq) -{ - /* FIXME just implement this, like pathmove but without - * JTAG-specific state transition checking. Then update - * zy1000_interface to report that it's supported. - * - * Eventually interface_jtag_add_pathmove() could vanish. - */ - return ERROR_JTAG_NOT_IMPLEMENTED; + return interface_add_tms_seq(state_count, seq, cur_state); } void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count) @@ -963,6 +983,7 @@ static const struct command_registration zy1000_commands[] = { struct jtag_interface zy1000_interface = { .name = "ZY1000", + .supported = DEBUG_CAP_TMS_SEQ, .execute_queue = NULL, .speed = zy1000_speed, .commands = zy1000_commands, commit 761d4555b8f8c8eb2b899dee16584656a43b6444 Author: Ãyvind Harboe <oyv...@zy...> Date: Mon Mar 1 08:22:12 2010 +0100 jtag: the post TAP state is now passed to the drivers after clocking out a tms sequence, then the TAP will be in some state. This state is now handed to the drivers. TAP_INVALID is a possible state after a TMS sequence if switching to SWD. Signed-off-by: Ãyvind Harboe <oyv...@zy...> diff --git a/src/jtag/core.c b/src/jtag/core.c index 7f417b7..d43bd1c 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -512,7 +512,7 @@ int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state) jtag_checks(); cmd_queue_cur_state = state; - retval = interface_add_tms_seq(nbits, seq); + retval = interface_add_tms_seq(nbits, seq, state); jtag_set_error(retval); return retval; } diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c index 14efe96..ca59239 100644 --- a/src/jtag/drivers/driver.c +++ b/src/jtag/drivers/driver.c @@ -388,7 +388,7 @@ int interface_jtag_add_tlr(void) return ERROR_OK; } -int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq) +int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state) { struct jtag_command *cmd; diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h index 5caec58..810bb0e 100644 --- a/src/jtag/minidriver.h +++ b/src/jtag/minidriver.h @@ -67,7 +67,8 @@ int interface_jtag_add_tlr(void); int interface_jtag_add_pathmove(int num_states, const tap_state_t* path); int interface_jtag_add_runtest(int num_cycles, tap_state_t endstate); -int interface_add_tms_seq(unsigned num_bits, const uint8_t *bits); +int interface_add_tms_seq(unsigned num_bits, + const uint8_t *bits, enum tap_state state); /** * This drives the actual srst and trst pins. srst will always be 0 diff --git a/src/jtag/minidummy/minidummy.c b/src/jtag/minidummy/minidummy.c index 6410c2d..705f1b4 100644 --- a/src/jtag/minidummy/minidummy.c +++ b/src/jtag/minidummy/minidummy.c @@ -147,7 +147,7 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) return ERROR_OK; } -int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq) +int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state) { /* synchronously do the operation here */ ----------------------------------------------------------------------- Summary of changes: src/jtag/core.c | 2 +- src/jtag/drivers/driver.c | 2 +- src/jtag/minidriver.h | 3 +- src/jtag/minidummy/minidummy.c | 2 +- src/jtag/zy1000/zy1000.c | 61 +++++++++++++++++++++++++++------------- 5 files changed, 46 insertions(+), 24 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: Spencer O. <nt...@us...> - 2010-03-01 00:11:59
|
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 409e23e39b955d92c8e879143d2b979b7de799e9 (commit) via 57fc63f9f16934be777a14707d518ea9c9c3db80 (commit) via c9560ba19071b2f988b0210ad03e6d9e8eca5edb (commit) via 73c1cff7c242566d995e7b77de0fcec9fe50a6bb (commit) via 8d13a4662647c33901592f699fcf544d88cfe443 (commit) via 9d6ede25ddb0863873f84b6a55f4300891429049 (commit) via 550abe7396f60274ffd0c5f373eda046af9d9a85 (commit) via 4c9f29bd9c9e38c3f495f8c26869f4dfe8fe9983 (commit) via b8d8953ae9995829a61ce7b34e544f004bb23c55 (commit) via a851ce0d6f2b961f94e09746304e0fb0dad6a15f (commit) from 0324eb24967088f753bc2fd997b4c18f4ea988c8 (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 409e23e39b955d92c8e879143d2b979b7de799e9 Author: Spencer Oliver <nt...@us...> Date: Sun Feb 28 23:06:49 2010 +0000 armv4_5: remove core_type check in mcr/mrc cmd core_type check is not required as the core function will be null for cores that do not support the mcr/mrc functions. Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 0488785..1e9a296 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -840,13 +840,6 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } - if (arm->core_type == ARM_MODE_THREAD) - { - /* armv7m not supported */ - LOG_ERROR("Unsupported Command"); - return ERROR_OK; - } - if ((argc < 6) || (argc > 7)) { /* FIXME use the command name to verify # params... */ LOG_ERROR("%s: wrong number of arguments", __func__); commit 57fc63f9f16934be777a14707d518ea9c9c3db80 Author: Spencer Oliver <nt...@us...> Date: Sun Feb 28 22:52:06 2010 +0000 cm3-ftest: change to use arm disassemble Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/testing/examples/cortex/cm3-ftest.cfg b/testing/examples/cortex/cm3-ftest.cfg index 2dae249..2c7809d 100644 --- a/testing/examples/cortex/cm3-ftest.cfg +++ b/testing/examples/cortex/cm3-ftest.cfg @@ -63,7 +63,7 @@ proc load_and_run { name halfwords n_instr } { mwh $addr 0xe7fe # disassemble, as sanity check and what's-happening trace - cortex_m3 disassemble 0x20000000 [expr 1 + $n_instr ] + arm disassemble 0x20000000 [expr 1 + $n_instr ] # Assume that block of code is at most 16 halfwords long. # Create a basic table of loop-to-self exception handlers. commit c9560ba19071b2f988b0210ad03e6d9e8eca5edb Author: Spencer Oliver <nt...@us...> Date: Sun Feb 28 22:40:23 2010 +0000 stellaris: recover_command use usleep rather than sleep windows api does not define a posix sleep, use usleep that has an openocd wrapper to the win32 native function. Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index b80daed..c9c800e 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -1215,7 +1215,7 @@ COMMAND_HANDLER(stellaris_handle_recover_command) retval = jtag_execute_queue(); /* wait 400+ msec ... OK, "1+ second" is simpler */ - sleep(1); + usleep(1000); /* USER INTERVENTION required for the power cycle * Restarting OpenOCD is likely needed because of mode switching. commit 73c1cff7c242566d995e7b77de0fcec9fe50a6bb Author: Spencer Oliver <nt...@us...> Date: Sun Feb 28 22:37:53 2010 +0000 FT2232: add missing enum when using ftd2xx library Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c index 43e7b9f..38195c7 100644 --- a/src/jtag/drivers/ft2232.c +++ b/src/jtag/drivers/ft2232.c @@ -86,6 +86,16 @@ /* FT2232 access library includes */ #if BUILD_FT2232_FTD2XX == 1 #include <ftd2xx.h> + +enum ftdi_interface +{ + INTERFACE_ANY = 0, + INTERFACE_A = 1, + INTERFACE_B = 2, + INTERFACE_C = 3, + INTERFACE_D = 4 +}; + #elif BUILD_FT2232_LIBFTDI == 1 #include <ftdi.h> #endif commit 8d13a4662647c33901592f699fcf544d88cfe443 Author: Spencer Oliver <nt...@us...> Date: Fri Feb 26 23:30:30 2010 +0000 semihosting: add armv7m semihosting support do_semihosting and arm_semihosting now check the core type and use the generic arm structure. Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/target/arm_semihosting.c b/src/target/arm_semihosting.c index 24a4de5..2f50a4a 100644 --- a/src/target/arm_semihosting.c +++ b/src/target/arm_semihosting.c @@ -39,6 +39,9 @@ #include "arm.h" #include "armv4_5.h" +#include "arm7_9_common.h" +#include "armv7m.h" +#include "cortex_m3.h" #include "register.h" #include "arm_semihosting.h" #include <helper/binarybuffer.h> @@ -62,14 +65,19 @@ static int open_modeflags[12] = { static int do_semihosting(struct target *target) { - struct arm *armv4_5 = target_to_arm(target); - uint32_t r0 = buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32); - uint32_t r1 = buf_get_u32(armv4_5->core_cache->reg_list[1].value, 0, 32); - uint32_t lr = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, ARM_MODE_SVC, 14).value, 0, 32); - uint32_t spsr = buf_get_u32(armv4_5->spsr->value, 0, 32);; + struct arm *arm = target_to_arm(target); + uint32_t r0 = buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32); + uint32_t r1 = buf_get_u32(arm->core_cache->reg_list[1].value, 0, 32); + uint32_t lr, spsr; uint8_t params[16]; int retval, result; + if (is_arm7_9(target_to_arm7_9(target))) + { + lr = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, ARM_MODE_SVC, 14).value, 0, 32); + spsr = buf_get_u32(arm->spsr->value, 0, 32);; + } + /* * TODO: lots of security issues are not considered yet, such as: * - no validation on target provided file descriptors @@ -105,10 +113,10 @@ static int do_semihosting(struct target *target) * written file */ result = open((char *)fn, open_modeflags[m], 0644); } - armv4_5->semihosting_errno = errno; + arm->semihosting_errno = errno; } else { result = -1; - armv4_5->semihosting_errno = EINVAL; + arm->semihosting_errno = EINVAL; } } break; @@ -120,7 +128,7 @@ static int do_semihosting(struct target *target) else { int fd = target_buffer_get_u32(target, params+0); result = close(fd); - armv4_5->semihosting_errno = errno; + arm->semihosting_errno = errno; } break; @@ -159,7 +167,7 @@ static int do_semihosting(struct target *target) uint8_t *buf = malloc(l); if (!buf) { result = -1; - armv4_5->semihosting_errno = ENOMEM; + arm->semihosting_errno = ENOMEM; } else { retval = target_read_buffer(target, a, l, buf); if (retval != ERROR_OK) { @@ -167,7 +175,7 @@ static int do_semihosting(struct target *target) return retval; } result = write(fd, buf, l); - armv4_5->semihosting_errno = errno; + arm->semihosting_errno = errno; if (result >= 0) result = l - result; free(buf); @@ -186,10 +194,10 @@ static int do_semihosting(struct target *target) uint8_t *buf = malloc(l); if (!buf) { result = -1; - armv4_5->semihosting_errno = ENOMEM; + arm->semihosting_errno = ENOMEM; } else { result = read(fd, buf, l); - armv4_5->semihosting_errno = errno; + arm->semihosting_errno = errno; if (result >= 0) { retval = target_write_buffer(target, a, result, buf); if (retval != ERROR_OK) { @@ -229,7 +237,7 @@ static int do_semihosting(struct target *target) int fd = target_buffer_get_u32(target, params+0); off_t pos = target_buffer_get_u32(target, params+4); result = lseek(fd, pos, SEEK_SET); - armv4_5->semihosting_errno = errno; + arm->semihosting_errno = errno; if (result == pos) result = 0; } @@ -244,7 +252,7 @@ static int do_semihosting(struct target *target) struct stat buf; result = fstat(fd, &buf); if (result == -1) { - armv4_5->semihosting_errno = errno; + arm->semihosting_errno = errno; result = -1; break; } @@ -266,10 +274,10 @@ static int do_semihosting(struct target *target) return retval; fn[l] = 0; result = remove((char *)fn); - armv4_5->semihosting_errno = errno; + arm->semihosting_errno = errno; } else { result = -1; - armv4_5->semihosting_errno = EINVAL; + arm->semihosting_errno = EINVAL; } } break; @@ -294,10 +302,10 @@ static int do_semihosting(struct target *target) fn1[l1] = 0; fn2[l2] = 0; result = rename((char *)fn1, (char *)fn2); - armv4_5->semihosting_errno = errno; + arm->semihosting_errno = errno; } else { result = -1; - armv4_5->semihosting_errno = EINVAL; + arm->semihosting_errno = EINVAL; } } break; @@ -307,7 +315,7 @@ static int do_semihosting(struct target *target) break; case 0x13: /* SYS_ERRNO */ - result = armv4_5->semihosting_errno; + result = arm->semihosting_errno; break; case 0x15: /* SYS_GET_CMDLINE */ @@ -383,25 +391,37 @@ static int do_semihosting(struct target *target) fprintf(stderr, "semihosting: unsupported call %#x\n", (unsigned) r0); result = -1; - armv4_5->semihosting_errno = ENOTSUP; + arm->semihosting_errno = ENOTSUP; } /* resume execution to the original mode */ - /* return value in R0 */ - buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, result); - armv4_5->core_cache->reg_list[0].dirty = 1; - - /* LR --> PC */ - buf_set_u32(armv4_5->pc->value, 0, 32, lr); - armv4_5->pc->dirty = 1; - - /* saved PSR --> current PSR */ - buf_set_u32(armv4_5->cpsr->value, 0, 32, spsr); - armv4_5->cpsr->dirty = 1; - armv4_5->core_mode = spsr & 0x1f; - if (spsr & 0x20) - armv4_5->core_state = ARM_STATE_THUMB; + if (is_arm7_9(target_to_arm7_9(target))) + { + /* return value in R0 */ + buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, result); + arm->core_cache->reg_list[0].dirty = 1; + + /* LR --> PC */ + buf_set_u32(arm->core_cache->reg_list[15].value, 0, 32, lr); + arm->core_cache->reg_list[15].dirty = 1; + + /* saved PSR --> current PSR */ + buf_set_u32(arm->cpsr->value, 0, 32, spsr); + arm->cpsr->dirty = 1; + arm->core_mode = spsr & 0x1f; + if (spsr & 0x20) + arm->core_state = ARM_STATE_THUMB; + } + else + { + /* resume execution, this will be pc+2 to skip over the + * bkpt instruction */ + + /* return result in R0 */ + buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, result); + arm->core_cache->reg_list[0].dirty = 1; + } return target_resume(target, 1, 0, 0, 0); } @@ -425,60 +445,90 @@ int arm_semihosting(struct target *target, int *retval) uint32_t pc, lr, spsr; struct reg *r; - if (!arm->is_semihosting || arm->core_mode != ARM_MODE_SVC) + if (!arm->is_semihosting) return 0; - /* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */ - r = arm->pc; - pc = buf_get_u32(r->value, 0, 32); - if (pc != 0x00000008 && pc != 0xffff0008) - return 0; + if (is_arm7_9(target_to_arm7_9(target))) + { + if (arm->core_mode != ARM_MODE_SVC) + return 0; - r = arm_reg_current(arm, 14); - lr = buf_get_u32(r->value, 0, 32); + /* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */ + r = arm->pc; + pc = buf_get_u32(r->value, 0, 32); + if (pc != 0x00000008 && pc != 0xffff0008) + return 0; - /* Core-specific code should make sure SPSR is retrieved - * when the above checks pass... - */ - if (!arm->spsr->valid) { - LOG_ERROR("SPSR not valid!"); - *retval = ERROR_FAIL; - return 1; - } + r = arm_reg_current(arm, 14); + lr = buf_get_u32(r->value, 0, 32); - spsr = buf_get_u32(arm->spsr->value, 0, 32); + /* Core-specific code should make sure SPSR is retrieved + * when the above checks pass... + */ + if (!arm->spsr->valid) { + LOG_ERROR("SPSR not valid!"); + *retval = ERROR_FAIL; + return 1; + } - /* check instruction that triggered this trap */ - if (spsr & (1 << 5)) { - /* was in Thumb (or ThumbEE) mode */ - uint8_t insn_buf[2]; - uint16_t insn; + spsr = buf_get_u32(arm->spsr->value, 0, 32); - *retval = target_read_memory(target, lr-2, 2, 1, insn_buf); - if (*retval != ERROR_OK) - return 1; - insn = target_buffer_get_u16(target, insn_buf); + /* check instruction that triggered this trap */ + if (spsr & (1 << 5)) { + /* was in Thumb (or ThumbEE) mode */ + uint8_t insn_buf[2]; + uint16_t insn; + + *retval = target_read_memory(target, lr-2, 2, 1, insn_buf); + if (*retval != ERROR_OK) + return 1; + insn = target_buffer_get_u16(target, insn_buf); - /* SVC 0xab */ - if (insn != 0xDFAB) + /* SVC 0xab */ + if (insn != 0xDFAB) + return 0; + } else if (spsr & (1 << 24)) { + /* was in Jazelle mode */ + return 0; + } else { + /* was in ARM mode */ + uint8_t insn_buf[4]; + uint32_t insn; + + *retval = target_read_memory(target, lr-4, 4, 1, insn_buf); + if (*retval != ERROR_OK) + return 1; + insn = target_buffer_get_u32(target, insn_buf); + + /* SVC 0x123456 */ + if (insn != 0xEF123456) + return 0; + } + } + else if (is_armv7m(target_to_armv7m(target))) + { + uint16_t insn; + + if (target->debug_reason != DBG_REASON_BREAKPOINT) return 0; - } else if (spsr & (1 << 24)) { - /* was in Jazelle mode */ - return 0; - } else { - /* was in ARM mode */ - uint8_t insn_buf[4]; - uint32_t insn; - *retval = target_read_memory(target, lr-4, 4, 1, insn_buf); + r = arm->pc; + pc = buf_get_u32(r->value, 0, 32); + + pc &= ~1; + *retval = target_read_u16(target, pc, &insn); if (*retval != ERROR_OK) return 1; - insn = target_buffer_get_u32(target, insn_buf); - /* SVC 0x123456 */ - if (insn != 0xEF123456) + /* bkpt 0xAB */ + if (insn != 0xBEAB) return 0; } + else + { + LOG_ERROR("Unsupported semi-hosting Target"); + return 0; + } *retval = do_semihosting(target); return 1; diff --git a/src/target/armv7m.c b/src/target/armv7m.c index ec11176..65e03bf 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -469,14 +469,15 @@ int armv7m_arch_state(struct target *target) sp = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_R13].value, 0, 32); LOG_USER("target halted due to %s, current mode: %s %s\n" - "xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32, + "xPSR: %#8.8" PRIx32 " pc: %#8.8" PRIx32 " %csp: %#8.8" PRIx32 "%s", debug_reason_name(target), armv7m_mode_strings[armv7m->core_mode], armv7m_exception_string(armv7m->exception_number), buf_get_u32(arm->cpsr->value, 0, 32), buf_get_u32(arm->pc->value, 0, 32), (ctrl & 0x02) ? 'p' : 'm', - sp); + sp, + arm->is_semihosting ? ", semihosting" : ""); return ERROR_OK; } @@ -529,6 +530,12 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) return cache; } +int armv7m_setup_semihosting(struct target *target, int enable) +{ + /* nothing todo for armv7m */ + return ERROR_OK; +} + /** Sets up target as a generic ARMv7-M core */ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m) { @@ -538,6 +545,7 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m) arm->core_type = ARM_MODE_THREAD; arm->arch_info = armv7m; + arm->setup_semihosting = armv7m_setup_semihosting; /* FIXME remove v7m-specific r/w core_reg functions; * use the generic ARM core support.. diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 0aa7ac1..aecf371 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -38,7 +38,7 @@ #include "arm_disassembler.h" #include "register.h" #include "arm_opcodes.h" - +#include "arm_semihosting.h" /* NOTE: most of this should work fine for the Cortex-M1 and * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M. @@ -495,6 +495,9 @@ static int cortex_m3_poll(struct target *target) if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK) return retval; + if (arm_semihosting(target, &retval) != 0) + return retval; + target_call_event_callbacks(target, TARGET_EVENT_HALTED); } if (prev_target_state == TARGET_DEBUG_RUNNING) commit 9d6ede25ddb0863873f84b6a55f4300891429049 Author: Spencer Oliver <nt...@us...> Date: Fri Feb 26 23:29:38 2010 +0000 semihosting: move semihosting cmd to arm cmd group Move semihosting cmd to the arm cmd group. Targets that support semihosting will setup the setup_semihosting callback function. Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/doc/openocd.texi b/doc/openocd.texi index d54ad12..507498f 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6021,6 +6021,18 @@ Display a table of all banked core registers, fetching the current value from ev core mode if necessary. @end deffn +@deffn Command {arm semihosting} [@option{enable}|@option{disable}] +@cindex ARM semihosting +Display status of semihosting, after optionally changing that status. + +Semihosting allows for code executing on an ARM target to use the +I/O facilities on the host computer i.e. the system where OpenOCD +is running. The target application must be linked against a library +implementing the ARM semihosting convention that forwards operation +requests by using a special SVC instruction that is trapped at the +Supervisor Call vector by OpenOCD. +@end deffn + @section ARMv4 and ARMv5 Architecture @cindex ARMv4 @cindex ARMv5 @@ -6073,18 +6085,6 @@ cables (FT2232), but might be unsafe if used with targets running at very low speeds, like the 32kHz startup clock of an AT91RM9200. @end deffn -@deffn Command {arm7_9 semihosting} [@option{enable}|@option{disable}] -@cindex ARM semihosting -Display status of semihosting, after optionally changing that status. - -Semihosting allows for code executing on an ARM target to use the -I/O facilities on the host computer i.e. the system where OpenOCD -is running. The target application must be linked against a library -implementing the ARM semihosting convention that forwards operation -requests by using a special SVC instruction that is trapped at the -Supervisor Call vector by OpenOCD. -@end deffn - @subsection ARM720T specific commands @cindex ARM720T diff --git a/src/target/arm.h b/src/target/arm.h index 6b304e9..ee4bd76 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -132,6 +132,8 @@ struct arm { /** Value to be returned by semihosting SYS_ERRNO request. */ int semihosting_errno; + int (*setup_semihosting)(struct target *target, int enable); + /** Backpointer to the target. */ struct target *target; diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 2176729..f9deb83 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2834,54 +2834,32 @@ COMMAND_HANDLER(handle_arm7_9_dcc_downloads_command) return ERROR_OK; } -COMMAND_HANDLER(handle_arm7_9_semihosting_command) +int arm7_9_setup_semihosting(struct target *target, int enable) { - struct target *target = get_current_target(CMD_CTX); struct arm7_9_common *arm7_9 = target_to_arm7_9(target); if (!is_arm7_9(arm7_9)) { - command_print(CMD_CTX, "current target isn't an ARM7/ARM9 target"); + LOG_USER("current target isn't an ARM7/ARM9 target"); return ERROR_TARGET_INVALID; } - if (CMD_ARGC > 0) - { - int semihosting; - - COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting); - - if (!target_was_examined(target)) - { - LOG_ERROR("Target not examined yet"); - return ERROR_FAIL; - } - - if (arm7_9->has_vector_catch) { - struct reg *vector_catch = &arm7_9->eice_cache - ->reg_list[EICE_VEC_CATCH]; - - if (!vector_catch->valid) - embeddedice_read_reg(vector_catch); - buf_set_u32(vector_catch->value, 2, 1, semihosting); - embeddedice_store_reg(vector_catch); - } else { - /* TODO: allow optional high vectors and/or BKPT_HARD */ - if (semihosting) - breakpoint_add(target, 8, 4, BKPT_SOFT); - else - breakpoint_remove(target, 8); - } - - /* FIXME never let that "catch" be dropped! */ - arm7_9->armv4_5_common.is_semihosting = semihosting; + if (arm7_9->has_vector_catch) { + struct reg *vector_catch = &arm7_9->eice_cache + ->reg_list[EICE_VEC_CATCH]; + if (!vector_catch->valid) + embeddedice_read_reg(vector_catch); + buf_set_u32(vector_catch->value, 2, 1, enable); + embeddedice_store_reg(vector_catch); + } else { + /* TODO: allow optional high vectors and/or BKPT_HARD */ + if (enable) + breakpoint_add(target, 8, 4, BKPT_SOFT); + else + breakpoint_remove(target, 8); } - command_print(CMD_CTX, "semihosting is %s", - arm7_9->armv4_5_common.is_semihosting - ? "enabled" : "disabled"); - return ERROR_OK; } @@ -2906,6 +2884,7 @@ int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9) armv4_5->read_core_reg = arm7_9_read_core_reg; armv4_5->write_core_reg = arm7_9_write_core_reg; armv4_5->full_context = arm7_9_full_context; + armv4_5->setup_semihosting = arm7_9_setup_semihosting; retval = arm_init_arch_info(target, armv4_5); if (retval != ERROR_OK) @@ -2939,13 +2918,6 @@ static const struct command_registration arm7_9_any_command_handlers[] = { .usage = "['enable'|'disable']", .help = "use DCC downloads for larger memory writes", }, - { - "semihosting", - .handler = handle_arm7_9_semihosting_command, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable']", - .help = "activate support for semihosting operations", - }, COMMAND_REGISTRATION_DONE }; const struct command_registration arm7_9_command_handlers[] = { diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 36101b0..0488785 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -951,6 +951,49 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_OK; } +COMMAND_HANDLER(handle_arm_semihosting_command) +{ + struct target *target = get_current_target(CMD_CTX); + struct arm *arm = target ? target_to_arm(target) : NULL; + + if (!is_arm(arm)) { + command_print(CMD_CTX, "current target isn't an ARM"); + return ERROR_FAIL; + } + + if (!arm->setup_semihosting) + { + command_print(CMD_CTX, "semihosting not supported for current target"); + } + + if (CMD_ARGC > 0) + { + int semihosting; + + COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting); + + if (!target_was_examined(target)) + { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + + if (arm->setup_semihosting(target, semihosting) != ERROR_OK) { + LOG_ERROR("Failed to Configure semihosting"); + return ERROR_FAIL; + } + + /* FIXME never let that "catch" be dropped! */ + arm->is_semihosting = semihosting; + } + + command_print(CMD_CTX, "semihosting is %s", + arm->is_semihosting + ? "enabled" : "disabled"); + + return ERROR_OK; +} + static const struct command_registration arm_exec_command_handlers[] = { { .name = "reg", @@ -985,6 +1028,13 @@ static const struct command_registration arm_exec_command_handlers[] = { .help = "read coprocessor register", .usage = "cpnum op1 CRn op2 CRm", }, + { + "semihosting", + .handler = handle_arm_semihosting_command, + .mode = COMMAND_EXEC, + .usage = "['enable'|'disable']", + .help = "activate support for semihosting operations", + }, COMMAND_REGISTRATION_DONE }; commit 550abe7396f60274ffd0c5f373eda046af9d9a85 Author: Spencer Oliver <nt...@us...> Date: Fri Feb 26 23:25:55 2010 +0000 CortexM3: move disassemble cmd to arm cmd group Rather than using a Cortex disassemble cmd, we now use the arm generic version. Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/doc/openocd.texi b/doc/openocd.texi index 9da2977..d54ad12 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6427,12 +6427,6 @@ If @var{value} is defined, first assigns that. @subsection Cortex-M3 specific commands @cindex Cortex-M3 -@deffn Command {cortex_m3 disassemble} address [count] -@cindex disassemble -Disassembles @var{count} Thumb2 instructions starting at @var{address}. -If @var{count} is not specified, a single instruction is disassembled. -@end deffn - @deffn Command {cortex_m3 maskisr} (@option{on}|@option{off}) Control masking (disabling) interrupts during target step/resume. @end deffn diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 3ebc34a..0aa7ac1 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -1899,50 +1899,6 @@ static int cortex_m3_verify_pointer(struct command_context *cmd_ctx, * cortexm3_target structure, which is only used with CM3 targets. */ -/* - * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well - * as at least ARM-1156T2. The interesting thing about Cortex-M is - * that *only* Thumb2 disassembly matters. There are also some small - * additions to Thumb2 that are specific to ARMv7-M. - */ -COMMAND_HANDLER(handle_cortex_m3_disassemble_command) -{ - int retval; - struct target *target = get_current_target(CMD_CTX); - struct cortex_m3_common *cortex_m3 = target_to_cm3(target); - uint32_t address; - unsigned long count = 1; - struct arm_instruction cur_instruction; - - retval = cortex_m3_verify_pointer(CMD_CTX, cortex_m3); - if (retval != ERROR_OK) - return retval; - - errno = 0; - switch (CMD_ARGC) { - case 2: - COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], count); - /* FALL THROUGH */ - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); - break; - default: - command_print(CMD_CTX, - "usage: cortex_m3 disassemble <address> [<count>]"); - return ERROR_OK; - } - - while (count--) { - retval = thumb2_opcode(target, address, &cur_instruction); - if (retval != ERROR_OK) - return retval; - command_print(CMD_CTX, "%s", cur_instruction.text); - address += cur_instruction.instruction_size; - } - - return ERROR_OK; -} - static const struct { char name[10]; unsigned mask; @@ -2057,13 +2013,6 @@ COMMAND_HANDLER(handle_cortex_m3_mask_interrupts_command) static const struct command_registration cortex_m3_exec_command_handlers[] = { { - .name = "disassemble", - .handler = handle_cortex_m3_disassemble_command, - .mode = COMMAND_EXEC, - .help = "disassemble Thumb2 instructions", - .usage = "address [count]", - }, - { .name = "maskisr", .handler = handle_cortex_m3_mask_interrupts_command, .mode = COMMAND_EXEC, commit 4c9f29bd9c9e38c3f495f8c26869f4dfe8fe9983 Author: Spencer Oliver <nt...@us...> Date: Fri Feb 26 23:14:51 2010 +0000 ARMv7M: add arm cmd group - Add arm cmd group to armv7m cmd chain. - arm cmd's now check the core type before running a cmd. - todo: add support for armv7m registers for reg cmd. Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index a4a15b4..36101b0 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -627,6 +627,12 @@ COMMAND_HANDLER(handle_armv4_5_reg_command) return ERROR_FAIL; } + if (armv4_5->core_type != ARM_MODE_ANY) + { + command_print(CMD_CTX, "Microcontroller Profile not supported - use standard reg cmd"); + return ERROR_OK; + } + if (!is_arm_mode(armv4_5->core_mode)) return ERROR_FAIL; @@ -706,6 +712,13 @@ COMMAND_HANDLER(handle_armv4_5_core_state_command) return ERROR_FAIL; } + if (armv4_5->core_type == ARM_MODE_THREAD) + { + /* armv7m not supported */ + command_print(CMD_CTX, "Unsupported Command"); + return ERROR_OK; + } + if (CMD_ARGC > 0) { if (strcmp(CMD_ARGV[0], "arm") == 0) @@ -723,7 +736,7 @@ COMMAND_HANDLER(handle_armv4_5_core_state_command) return ERROR_OK; } -COMMAND_HANDLER(handle_armv4_5_disassemble_command) +COMMAND_HANDLER(handle_arm_disassemble_command) { int retval = ERROR_OK; struct target *target = get_current_target(CMD_CTX); @@ -737,6 +750,12 @@ COMMAND_HANDLER(handle_armv4_5_disassemble_command) return ERROR_FAIL; } + if (arm->core_type == ARM_MODE_THREAD) + { + /* armv7m is always thumb mode */ + thumb = 1; + } + switch (CMD_ARGC) { case 3: if (strcmp(CMD_ARGV[2], "thumb") != 0) @@ -821,6 +840,13 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) return JIM_ERR; } + if (arm->core_type == ARM_MODE_THREAD) + { + /* armv7m not supported */ + LOG_ERROR("Unsupported Command"); + return ERROR_OK; + } + if ((argc < 6) || (argc > 7)) { /* FIXME use the command name to verify # params... */ LOG_ERROR("%s: wrong number of arguments", __func__); @@ -941,7 +967,7 @@ static const struct command_registration arm_exec_command_handlers[] = { }, { .name = "disassemble", - .handler = handle_armv4_5_disassemble_command, + .handler = handle_arm_disassemble_command, .mode = COMMAND_EXEC, .usage = "address [count ['thumb']]", .help = "disassemble instructions ", diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 056ac7b..ec11176 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -878,6 +878,9 @@ static const struct command_registration armv7m_exec_command_handlers[] = { }; const struct command_registration armv7m_command_handlers[] = { { + .chain = arm_command_handlers, + }, + { .name = "dap", .mode = COMMAND_EXEC, .help = "Cortex DAP command group", commit b8d8953ae9995829a61ce7b34e544f004bb23c55 Author: Spencer Oliver <nt...@us...> Date: Wed Jan 13 10:12:34 2010 +0000 MIPS: add mips algorithm support - add mips support for target algorithms. - added handlers for target_checksum_memory and target_blank_check_memory. - clean up long lines Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/target/mips32.c b/src/target/mips32.c index 5bb4104..b0cb79c 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -27,6 +27,8 @@ #endif #include "mips32.h" +#include "breakpoints.h" +#include "algorithm.h" #include "register.h" char* mips32_core_reg_list[] = @@ -319,9 +321,168 @@ int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, s return ERROR_OK; } -int mips32_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info) +/* run to exit point. return error if exit point was not reached. */ +static int mips32_run_and_wait(struct target *target, uint32_t entry_point, + int timeout_ms, uint32_t exit_point, struct mips32_common *mips32) { - /*TODO*/ + uint32_t pc; + int retval; + /* This code relies on the target specific resume() and poll()->debug_entry() + * sequence to write register values to the processor and the read them back */ + if ((retval = target_resume(target, 0, entry_point, 0, 1)) != ERROR_OK) + { + return retval; + } + + retval = target_wait_state(target, TARGET_HALTED, timeout_ms); + /* If the target fails to halt due to the breakpoint, force a halt */ + if (retval != ERROR_OK || target->state != TARGET_HALTED) + { + if ((retval = target_halt(target)) != ERROR_OK) + return retval; + if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK) + { + return retval; + } + return ERROR_TARGET_TIMEOUT; + } + + pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32); + if (pc != exit_point) + { + LOG_DEBUG("failed algoritm halted at 0x%" PRIx32 " ", pc); + return ERROR_TARGET_TIMEOUT; + } + + return ERROR_OK; +} + +int mips32_run_algorithm(struct target *target, int num_mem_params, + struct mem_param *mem_params, int num_reg_params, + struct reg_param *reg_params, uint32_t entry_point, + uint32_t exit_point, int timeout_ms, void *arch_info) +{ + struct mips32_common *mips32 = target_to_mips32(target); + struct mips32_algorithm *mips32_algorithm_info = arch_info; + enum mips32_isa_mode isa_mode = mips32->isa_mode; + + uint32_t context[MIPS32NUMCOREREGS]; + int i; + int retval = ERROR_OK; + + LOG_DEBUG("Running algorithm"); + + /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint + * at the exit point */ + + if (mips32->common_magic != MIPS32_COMMON_MAGIC) + { + LOG_ERROR("current target isn't a MIPS32 target"); + return ERROR_TARGET_INVALID; + } + + if (target->state != TARGET_HALTED) + { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* refresh core register cache */ + for (unsigned i = 0; i < MIPS32NUMCOREREGS; i++) + { + if (!mips32->core_cache->reg_list[i].valid) + mips32->read_core_reg(target, i); + context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32); + } + + for (i = 0; i < num_mem_params; i++) + { + if ((retval = target_write_buffer(target, mem_params[i].address, + mem_params[i].size, mem_params[i].value)) != ERROR_OK) + { + return retval; + } + } + + for (int i = 0; i < num_reg_params; i++) + { + struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0); + + if (!reg) + { + LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); + return ERROR_INVALID_ARGUMENTS; + } + + if (reg->size != reg_params[i].size) + { + LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", + reg_params[i].reg_name); + return ERROR_INVALID_ARGUMENTS; + } + + mips32_set_core_reg(reg, reg_params[i].value); + } + + mips32->isa_mode = mips32_algorithm_info->isa_mode; + + retval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32); + + if (retval != ERROR_OK) + return retval; + + for (i = 0; i < num_mem_params; i++) + { + if (mem_params[i].direction != PARAM_OUT) + { + if ((retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size, + mem_params[i].value)) != ERROR_OK) + { + return retval; + } + } + } + + for (i = 0; i < num_reg_params; i++) + { + if (reg_params[i].direction != PARAM_OUT) + { + struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0); + if (!reg) + { + LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); + return ERROR_INVALID_ARGUMENTS; + } + + if (reg->size != reg_params[i].size) + { + LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", + reg_params[i].reg_name); + return ERROR_INVALID_ARGUMENTS; + } + + buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32)); + } + } + + /* restore everything we saved before */ + for (i = 0; i < MIPS32NUMCOREREGS; i++) + { + uint32_t regvalue; + regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32); + if (regvalue != context[i]) + { + LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32, + mips32->core_cache->reg_list[i].name, context[i]); + buf_set_u32(mips32->core_cache->reg_list[i].value, + 0, 32, context[i]); + mips32->core_cache->reg_list[i].valid = 1; + mips32->core_cache->reg_list[i].dirty = 1; + } + } + + mips32->isa_mode = isa_mode; + return ERROR_OK; } @@ -397,7 +558,8 @@ int mips32_configure_break_unit(struct target *target) return retval; } - LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints, mips32->num_data_bpoints); + LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints, + mips32->num_data_bpoints); mips32->bp_scanned = 1; @@ -441,3 +603,150 @@ int mips32_enable_interrupts(struct target *target, int enable) return ERROR_OK; } + +int mips32_checksum_memory(struct target *target, uint32_t address, + uint32_t count, uint32_t* checksum) +{ + struct working_area *crc_algorithm; + struct reg_param reg_params[2]; + struct mips32_algorithm mips32_info; + int retval; + uint32_t i; + + static const uint32_t mips_crc_code[] = + { + 0x248C0000, /* addiu $t4, $a0, 0 */ + 0x24AA0000, /* addiu $t2, $a1, 0 */ + 0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */ + 0x10000010, /* beq $zero, $zero, ncomp */ + 0x240B0000, /* addiu $t3, $zero, 0 */ + /* nbyte: */ + 0x81850000, /* lb $a1, ($t4) */ + 0x218C0001, /* addi $t4, $t4, 1 */ + 0x00052E00, /* sll $a1, $a1, 24 */ + 0x3C0204C1, /* lui $v0, 0x04c1 */ + 0x00852026, /* xor $a0, $a0, $a1 */ + 0x34471DB7, /* ori $a3, $v0, 0x1db7 */ + 0x00003021, /* addu $a2, $zero, $zero */ + /* loop: */ + 0x00044040, /* sll $t0, $a0, 1 */ + 0x24C60001, /* addiu $a2, $a2, 1 */ + 0x28840000, /* slti $a0, $a0, 0 */ + 0x01074826, /* xor $t1, $t0, $a3 */ + 0x0124400B, /* movn $t0, $t1, $a0 */ + 0x28C30008, /* slti $v1, $a2, 8 */ + 0x1460FFF9, /* bne $v1, $zero, loop */ + 0x01002021, /* addu $a0, $t0, $zero */ + /* ncomp: */ + 0x154BFFF0, /* bne $t2, $t3, nbyte */ + 0x256B0001, /* addiu $t3, $t3, 1 */ + 0x7000003F, /* sdbbp */ + }; + + /* make sure we have a working area */ + if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK) + { + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + /* convert flash writing code into a buffer in target endianness */ + for (i = 0; i < ARRAY_SIZE(mips_crc_code); i++) + target_write_u32(target, crc_algorithm->address + i*sizeof(uint32_t), mips_crc_code[i]); + + mips32_info.common_magic = MIPS32_COMMON_MAGIC; + mips32_info.isa_mode = MIPS32_ISA_MIPS32; + + init_reg_param(®_params[0], "a0", 32, PARAM_IN_OUT); + buf_set_u32(reg_params[0].value, 0, 32, address); + + init_reg_param(®_params[1], "a1", 32, PARAM_OUT); + buf_set_u32(reg_params[1].value, 0, 32, count); + + if ((retval = target_run_algorithm(target, 0, NULL, 2, reg_params, + crc_algorithm->address, crc_algorithm->address + (sizeof(mips_crc_code)-4), 10000, + &mips32_info)) != ERROR_OK) + { + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + target_free_working_area(target, crc_algorithm); + return 0; + } + + *checksum = buf_get_u32(reg_params[0].value, 0, 32); + + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + + target_free_working_area(target, crc_algorithm); + + return ERROR_OK; +} + +/** Checks whether a memory region is zeroed. */ +int mips32_blank_check_memory(struct target *target, + uint32_t address, uint32_t count, uint32_t* blank) +{ + struct working_area *erase_check_algorithm; + struct reg_param reg_params[3]; + struct mips32_algorithm mips32_info; + int retval; + uint32_t i; + + static const uint32_t erase_check_code[] = + { + /* nbyte: */ + 0x80880000, /* lb $t0, ($a0) */ + 0x00C83024, /* and $a2, $a2, $t0 */ + 0x24A5FFFF, /* addiu $a1, $a1, -1 */ + 0x14A0FFFC, /* bne $a1, $zero, nbyte */ + 0x24840001, /* addiu $a0, $a0, 1 */ + 0x7000003F /* sdbbp */ + }; + + /* make sure we have a working area */ + if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK) + { + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + /* convert flash writing code into a buffer in target endianness */ + for (i = 0; i < ARRAY_SIZE(erase_check_code); i++) + { + target_write_u32(target, erase_check_algorithm->address + i*sizeof(uint32_t), + erase_check_code[i]); + } + + mips32_info.common_magic = MIPS32_COMMON_MAGIC; + mips32_info.isa_mode = MIPS32_ISA_MIPS32; + + init_reg_param(®_params[0], "a0", 32, PARAM_OUT); + buf_set_u32(reg_params[0].value, 0, 32, address); + + init_reg_param(®_params[1], "a1", 32, PARAM_OUT); + buf_set_u32(reg_params[1].value, 0, 32, count); + + init_reg_param(®_params[2], "a2", 32, PARAM_IN_OUT); + buf_set_u32(reg_params[2].value, 0, 32, 0xff); + + if ((retval = target_run_algorithm(target, 0, NULL, 3, reg_params, + erase_check_algorithm->address, + erase_check_algorithm->address + (sizeof(erase_check_code)-2), + 10000, &mips32_info)) != ERROR_OK) + { + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_params[2]); + target_free_working_area(target, erase_check_algorithm); + return 0; + } + + *blank = buf_get_u32(reg_params[2].value, 0, 32); + + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_params[2]); + + target_free_working_area(target, erase_check_algorithm); + + return ERROR_OK; +} diff --git a/src/target/mips32.h b/src/target/mips32.h index b731c68..94d29ff 100644 --- a/src/target/mips32.h +++ b/src/target/mips32.h @@ -85,6 +85,12 @@ struct mips32_core_reg struct mips32_common *mips32_common; }; +struct mips32_algorithm +{ + int common_magic; + enum mips32_isa_mode isa_mode; +}; + #define MIPS32_OP_BEQ 0x04 #define MIPS32_OP_BNE 0x05 #define MIPS32_OP_ADDI 0x08 @@ -164,5 +170,9 @@ int mips32_register_commands(struct command_context *cmd_ctx); int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size); +int mips32_checksum_memory(struct target *target, uint32_t address, + uint32_t count, uint32_t* checksum); +int mips32_blank_check_memory(struct target *target, + uint32_t address, uint32_t count, uint32_t* blank); #endif /*MIPS32_H*/ diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index 7d91d42..f20c69e 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -206,7 +206,8 @@ static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t ad return ERROR_OK; } -int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_t *code, int num_param_in, uint32_t *param_in, int num_param_out, uint32_t *param_out, int cycle) +int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_t *code, + int num_param_in, uint32_t *param_in, int num_param_out, uint32_t *param_out, int cycle) { uint32_t ejtag_ctrl; uint32_t address, data; diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 5f5aa72..f581ddf 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -32,61 +32,6 @@ #include "target_type.h" #include "register.h" -/* cli handling */ - -/* forward declarations */ -int mips_m4k_poll(struct target *target); -int mips_m4k_halt(struct target *target); -int mips_m4k_soft_reset_halt(struct target *target); -int mips_m4k_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution); -int mips_m4k_step(struct target *target, int current, uint32_t address, int handle_breakpoints); -int mips_m4k_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); -int mips_m4k_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); -int mips_m4k_init_target(struct command_context *cmd_ctx, struct target *target); -int mips_m4k_target_create(struct target *target, Jim_Interp *interp); - -int mips_m4k_examine(struct target *target); -int mips_m4k_assert_reset(struct target *target); -int mips_m4k_deassert_reset(struct target *target); -int mips_m4k_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t *checksum); - -struct target_type mips_m4k_target = -{ - .name = "mips_m4k", - - .poll = mips_m4k_poll, - .arch_state = mips32_arch_state, - - .target_request_data = NULL, - - .halt = mips_m4k_halt, - .resume = mips_m4k_resume, - .step = mips_m4k_step, - - .assert_reset = mips_m4k_assert_reset, - .deassert_reset = mips_m4k_deassert_reset, - .soft_reset_halt = mips_m4k_soft_reset_halt, - - .get_gdb_reg_list = mips32_get_gdb_reg_list, - - .read_memory = mips_m4k_read_memory, - .write_memory = mips_m4k_write_memory, - .bulk_write_memory = mips_m4k_bulk_write_memory, - .checksum_memory = mips_m4k_checksum_memory, - .blank_check_memory = NULL, - - .run_algorithm = mips32_run_algorithm, - - .add_breakpoint = mips_m4k_add_breakpoint, - .remove_breakpoint = mips_m4k_remove_breakpoint, - .add_watchpoint = mips_m4k_add_watchpoint, - .remove_watchpoint = mips_m4k_remove_watchpoint, - - .target_create = mips_m4k_target_create, - .init_target = mips_m4k_init_target, - .examine = mips_m4k_examine, -}; - int mips_m4k_examine_debug_reason(struct target *target) { uint32_t break_status; @@ -148,13 +93,8 @@ int mips_m4k_debug_entry(struct target *target) /* default to mips32 isa, it will be changed below if required */ mips32->isa_mode = MIPS32_ISA_MIPS32; - if (ejtag_info->impcode & EJTAG_IMP_MIPS16) - { - if (buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32) & 0x01) - { - /* core is running mips16e isa */ - mips32->isa_mode = MIPS32_ISA_MIPS16E; - } + if (ejtag_info->impcode & EJTAG_IMP_MIPS16) { + mips32->isa_mode = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1); } LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s", @@ -396,6 +336,10 @@ int mips_m4k_resume(struct target *target, int current, uint32_t address, int ha mips32->core_cache->reg_list[MIPS32_PC].valid = 1; } + if (ejtag_info->impcode & EJTAG_IMP_MIPS16) { + buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode); + } + resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32); mips32_restore_context(target); @@ -457,9 +401,12 @@ int mips_m4k_step(struct target *target, int current, uint32_t address, int hand buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address); /* the front-end may request us not to handle breakpoints */ - if (handle_breakpoints) - if ((breakpoint = breakpoint_find(target, buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32)))) + if (handle_breakpoints) { + breakpoint = breakpoint_find(target, + buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32)); + if (breakpoint) mips_m4k_unset_breakpoint(target, breakpoint); + } /* restore context */ mips32_restore_context(target); @@ -545,7 +492,8 @@ int mips_m4k_set_breakpoint(struct target *target, struct breakpoint *breakpoint { uint32_t verify = 0xffffffff; - if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK) + if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, + breakpoint->orig_instr)) != ERROR_OK) { return retval; } @@ -568,7 +516,8 @@ int mips_m4k_set_breakpoint(struct target *target, struct breakpoint *breakpoint { uint16_t verify = 0xffff; - if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK) + if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, + breakpoint->orig_instr)) != ERROR_OK) { return retval; } @@ -633,13 +582,15 @@ int mips_m4k_unset_breakpoint(struct target *target, struct breakpoint *breakpoi uint32_t current_instr; /* check that user program has not modified breakpoint instruction */ - if ((retval = target_read_memory(target, breakpoint->address, 4, 1, (uint8_t*)¤t_instr)) != ERROR_OK) + if ((retval = target_read_memory(target, breakpoint->address, 4, 1, + (uint8_t*)¤t_instr)) != ERROR_OK) { return retval; } if (current_instr == MIPS32_SDBBP) { - if ((retval = target_write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK) + if ((retval = target_write_memory(target, breakpoint->address, 4, 1, + breakpoint->orig_instr)) != ERROR_OK) { return retval; } @@ -650,14 +601,16 @@ int mips_m4k_unset_breakpoint(struct target *target, struct breakpoint *breakpoi uint16_t current_instr; /* check that user program has not modified breakpoint instruction */ - if ((retval = target_read_memory(target, breakpoint->address, 2, 1, (uint8_t*)¤t_instr)) != ERROR_OK) + if ((retval = target_read_memory(target, breakpoint->address, 2, 1, + (uint8_t*)¤t_instr)) != ERROR_OK) { return retval; } if (current_instr == MIPS16_SDBBP) { - if ((retval = target_write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK) + if ((retval = target_write_memory(target, breakpoint->address, 2, 1, + breakpoint->orig_instr)) != ERROR_OK) { return retval; } @@ -886,12 +839,14 @@ int mips_m4k_read_memory(struct target *target, uint32_t address, uint32_t size, return ERROR_OK; } -int mips_m4k_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) +int mips_m4k_write_memory(struct target *target, uint32_t address, uint32_t size, + uint32_t count, uint8_t *buffer) { struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; - LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); + LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", + address, size, count); if (target->state != TARGET_HALTED) { @@ -920,7 +875,8 @@ int mips_m4k_init_target(struct command_context *cmd_ctx, struct target *target) return ERROR_OK; } -int mips_m4k_init_arch_info(struct target *target, struct mips_m4k_common *mips_m4k, struct jtag_tap *tap) +int mips_m4k_init_arch_info(struct target *target, struct mips_m4k_common *mips_m4k, + struct jtag_tap *tap) { struct mips32_common *mips32 = &mips_m4k->mips32_common; @@ -973,7 +929,8 @@ int mips_m4k_examine(struct target *target) return ERROR_OK; } -int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer) +int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, + uint32_t count, uint8_t *buffer) { struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; @@ -1012,7 +969,8 @@ int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, uint32_t } } - retval = mips32_pracc_fastdata_xfer(ejtag_info, source, write, address, count, (uint32_t*) buffer); + retval = mips32_pracc_fastdata_xfer(ejtag_info, source, write, address, + count, (uint32_t*) buffer); if (retval != ERROR_OK) { /* FASTDATA access failed, try normal memory write */ @@ -1026,7 +984,39 @@ int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, uint32_t return retval; } -int mips_m4k_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t *checksum) +struct target_type mips_m4k_target = { - return ERROR_FAIL; /* use bulk read method */ -} + .name = "mips_m4k", + + .poll = mips_m4k_poll, + .arch_state = mips32_arch_state, + + .target_request_data = NULL, + + .halt = mips_m4k_halt, + .resume = mips_m4k_resume, + .step = mips_m4k_step, + + .assert_reset = mips_m4k_assert_reset, + .deassert_reset = mips_m4k_deassert_reset, + .soft_reset_halt = mips_m4k_soft_reset_halt, + + .get_gdb_reg_list = mips32_get_gdb_reg_list, + + .read_memory = mips_m4k_read_memory, + .write_memory = mips_m4k_write_memory, + .bulk_write_memory = mips_m4k_bulk_write_memory, + .checksum_memory = mips32_checksum_memory, + .blank_check_memory = mips32_blank_check_memory, + + .run_algorithm = mips32_run_algorithm, + + .add_breakpoint = mips_m4k_add_breakpoint, + .remove_breakpoint = mips_m4k_remove_breakpoint, + .add_watchpoint = mips_m4k_add_watchpoint, + .remove_watchpoint = mips_m4k_remove_watchpoint, + + .target_create = mips_m4k_target_create, + .init_target = mips_m4k_init_target, + .examine = mips_m4k_examine, +}; commit a851ce0d6f2b961f94e09746304e0fb0dad6a15f Author: Spencer Oliver <nt...@us...> Date: Tue Feb 2 13:22:07 2010 +0000 ARMv7M: use software breakpoints for algorithms - armv7m_run_algorithm now requires all algorithms to use a software breakpoint at their exit address - updated all algorithms to support this Signed-off-by: Spencer Oliver <nt...@us...> diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c index 1b2f27c..5f013ed 100644 --- a/src/flash/nor/at91sam3.c +++ b/src/flash/nor/at91sam3.c @@ -2046,9 +2046,7 @@ sam3_page_write_opcodes[] = { 0x10,0xf0,0x01,0x0f, // 41 0024 FBD0 beq .L4 0xfb,0xd0, - // 42 .done: - // 43 0026 FEE7 b .done - 0xfe,0xe7 + 0x00,0xBE /* bkpt #0 */ }; diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c index fc2b1cf..6674f17 100644 --- a/src/flash/nor/lpc2000.c +++ b/src/flash/nor/lpc2000.c @@ -267,7 +267,7 @@ static int lpc2000_iap_call(struct flash_bank *bank, int code, uint32_t param_ta target_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12)); target_buffer_set_u32(target, jump_gate + 4, - ARMV4_5_T_B(0xfffffe)); + ARMV5_T_BKPT(0)); break; case lpc2000_v1: case lpc2000_v2: diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index 21a0cff..b80daed 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -805,8 +805,7 @@ static const uint8_t stellaris_write_code[] = 0x04,0x36, /* adds r6, r6, #4 */ 0x96,0x42, /* cmp r6, r2 */ 0xF4,0xD1, /* bne mainloop */ - /* exit: */ - 0xFE,0xE7, /* b exit */ + 0x00,0xBE, /* bkpt #0 */ /* pFLASH_CTRL_BASE: */ 0x00,0xD0,0x0F,0x40, /* .word 0x400FD000 */ /* FLASHWRITECMD: */ diff --git a/src/flash/nor/stm32x.c b/src/flash/nor/stm32x.c index bfdd3cd..53fc4ea 100644 --- a/src/flash/nor/stm32x.c +++ b/src/flash/nor/stm32x.c @@ -459,8 +459,7 @@ static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t 0x01, 0xD1, /* bne exit */ 0x01, 0x3A, /* subs r2, r2, #1 */ 0xED, 0xD1, /* bne write */ - /* exit: */ - 0xFE, 0xE7, /* b exit */ + 0x00, 0xBE, /* bkpt #0 */ 0x10, 0x20, 0x02, 0x40, /* STM32_FLASH_CR: .word 0x40022010 */ 0x0C, 0x20, 0x02, 0x40 /* STM32_FLASH_SR: .word 0x4002200C */ }; diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 466c0b2..056ac7b 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -338,6 +338,9 @@ int armv7m_run_algorithm(struct target *target, int retval = ERROR_OK; uint32_t context[ARMV7M_NUM_REGS]; + /* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint + * at the exit point */ + if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC) { LOG_ERROR("current target isn't an ARMV7M target"); @@ -395,22 +398,8 @@ int armv7m_run_algorithm(struct target *target, armv7m->core_cache->reg_list[ARMV7M_CONTROL].valid = 1; } - /* REVISIT speed things up (3% or so in one case) by requiring - * algorithms to include a BKPT instruction at each exit point. - * This eliminates overheads of adding/removing a breakpoint. - */ - - /* ARMV7M always runs in Thumb state */ - if ((retval = breakpoint_add(target, exit_point, 2, BKPT_SOFT)) != ERROR_OK) - { - LOG_ERROR("can't add breakpoint to finish algorithm execution"); - return ERROR_TARGET_FAILURE; - } - retval = armv7m_run_and_wait(target, entry_point, timeout_ms, exit_point, armv7m); - breakpoint_remove(target, exit_point); - if (retval != ERROR_OK) { return retval; @@ -594,8 +583,7 @@ int armv7m_checksum_memory(struct target *target, /* ncomp: */ 0x429C, /* cmp r4, r3 */ 0xD1E9, /* bne nbyte */ - /* end: */ - 0xE7FE, /* b end */ + 0xBE00, /* bkpt #0 */ 0x1DB7, 0x04C1 /* CRC32XOR: .word 0x04C11DB7 */ }; @@ -659,8 +647,7 @@ int armv7m_blank_check_memory(struct target *target, 0xEA02, 0x0203, /* and r2, r2, r3 */ 0x3901, /* subs r1, r1, #1 */ 0xD1F9, /* bne loop */ - /* end: */ - 0xE7FE, /* b end */ + 0xBE00, /* bkpt #0 */ }; /* make sure we have a working area */ ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 30 ++-- src/flash/nor/at91sam3.c | 4 +- src/flash/nor/lpc2000.c | 2 +- src/flash/nor/stellaris.c | 5 +- src/flash/nor/stm32x.c | 3 +- src/jtag/drivers/ft2232.c | 10 + src/target/arm.h | 2 + src/target/arm7_9_common.c | 60 ++----- src/target/arm_semihosting.c | 196 +++++++++++++-------- src/target/armv4_5.c | 73 ++++++++- src/target/armv7m.c | 38 ++-- src/target/cortex_m3.c | 56 +------ src/target/mips32.c | 315 ++++++++++++++++++++++++++++++++- src/target/mips32.h | 10 + src/target/mips32_pracc.c | 3 +- src/target/mips_m4k.c | 146 +++++++-------- testing/examples/cortex/cm3-ftest.cfg | 2 +- 17 files changed, 654 insertions(+), 301 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-02-28 19:34:50
|
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 0324eb24967088f753bc2fd997b4c18f4ea988c8 (commit) from 63763345d94b11f106c832c23e8ad730a4485723 (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 0324eb24967088f753bc2fd997b4c18f4ea988c8 Author: Mariano Alvira <ma...@de...> Date: Sun Feb 28 10:33:46 2010 -0800 Add board/redbee-usb.cfg The Redbee USB is a small form-factor usb stick from Redwire, LLC (www.redwirellc.com/store), built around a Freescale MC13224V ARM7TDMI + 802.15.4 radio (plus antenna). It includes an FT2232H for debugging, with Channel B connected to the mc13224v's JTAG interface (unusual) and Channel A connected to UART1. Signed-off-by: David Brownell <dbr...@us...> diff --git a/doc/openocd.texi b/doc/openocd.texi index c6113ab..9da2977 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2131,6 +2131,7 @@ to debug some other target. It can support the SWO trace mechanism. @item @b{oocdlink} OOCDLink @c oocdlink ~= jtagkey_prototype_v1 @item @b{redbee-econotag} Integrated with a Redbee development board. +@item @b{redbee-usb} Integrated with a Redbee USB-stick development board. @item @b{sheevaplug} Marvell Sheevaplug development kit @item @b{signalyzer} Xverve Signalyzer @item @b{stm32stick} Hitex STM32 Performance Stick diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c index d2e96d0..43e7b9f 100644 --- a/src/jtag/drivers/ft2232.c +++ b/src/jtag/drivers/ft2232.c @@ -269,6 +269,11 @@ static const struct ft2232_layout ft2232_layouts[] = .init = redbee_init, .reset = redbee_reset, }, + { .name = "redbee-usb", + .init = redbee_init, + .reset = redbee_reset, + .channel = INTERFACE_B, + }, { .name = NULL, /* END OF TABLE */ }, }; diff --git a/tcl/board/redbee-usb.cfg b/tcl/board/redbee-usb.cfg new file mode 100644 index 0000000..3aa68c1 --- /dev/null +++ b/tcl/board/redbee-usb.cfg @@ -0,0 +1,8 @@ +source [find target/mc13224v.cfg] + +# The redbee-econotag has an onboard ft2232h with +# channel B wired to the JTAG pins on the mc13224v +# channel A is wired to UART1 on the mc13224v +interface ft2232 +ft2232_layout redbee-usb +ft2232_vid_pid 0x0403 0x6010 ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 1 + src/jtag/drivers/ft2232.c | 5 +++++ tcl/board/redbee-usb.cfg | 8 ++++++++ 3 files changed, 14 insertions(+), 0 deletions(-) create mode 100644 tcl/board/redbee-usb.cfg hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-02-28 07:55:16
|
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 63763345d94b11f106c832c23e8ad730a4485723 (commit) via e4a40d257d6c8fa393929cda50c0a1d777787da2 (commit) from e70d42a727bebc5ae0ce0b1386620d30ea00b05b (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 63763345d94b11f106c832c23e8ad730a4485723 Author: Mariano Alvira <ma...@de...> Date: Sat Feb 27 22:52:34 2010 -0800 add board/redbee-econotag.cfg and JTAG support The Redbee Econotag is an open hardware development kit from Redwire, LLC (www.redwirellc.com/store), for the Freescale MC13224V ARM7TDMI + 802.15.4 radio. It includes both an MC13224V and an FT2232H (for JTAG and UART support). It has flexible power supply options. Additional features are: - inverted-F pcb antenna - 36 GPIO brought out to 0.1" pin header (includes all peripheral pins) - Reset button - Two push buttons (on kbi1-5 and kbi0-4) - USB-A connector, powered from USB - up to 16V external input - pads for optional buck inductor - pads for optional 32.768kHz crystal - 2x LEDS on TX_ON and RX_ON [ dbr...@us...: shrink lines; texi ] Signed-off-by: David Brownell <dbr...@us...> diff --git a/doc/openocd.texi b/doc/openocd.texi index aa8bed1..c6113ab 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2130,6 +2130,7 @@ to debug some other target. It can support the SWO trace mechanism. @item @b{olimex-jtag} Olimex ARM-USB-OCD and ARM-USB-Tiny @item @b{oocdlink} OOCDLink @c oocdlink ~= jtagkey_prototype_v1 +@item @b{redbee-econotag} Integrated with a Redbee development board. @item @b{sheevaplug} Marvell Sheevaplug development kit @item @b{signalyzer} Xverve Signalyzer @item @b{stm32stick} Hitex STM32 Performance Stick diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c index 5c6b655..d2e96d0 100644 --- a/src/jtag/drivers/ft2232.c +++ b/src/jtag/drivers/ft2232.c @@ -162,6 +162,7 @@ static int icebear_jtag_init(void); static int cortino_jtag_init(void); static int signalyzer_h_init(void); static int ktlink_init(void); +static int redbee_init(void); /* reset procedures for supported layouts */ static void usbjtag_reset(int trst, int srst); @@ -176,6 +177,7 @@ static void sheevaplug_reset(int trst, int srst); static void icebear_jtag_reset(int trst, int srst); static void signalyzer_h_reset(int trst, int srst); static void ktlink_reset(int trst, int srst); +static void redbee_reset(int trst, int srst); /* blink procedures for layouts that support a blinking led */ static void olimex_jtag_blink(void); @@ -263,6 +265,10 @@ static const struct ft2232_layout ft2232_layouts[] = .reset = ktlink_reset, .blink = ktlink_blink }, + { .name = "redbee-econotag", + .init = redbee_init, + .reset = redbee_reset, + }, { .name = NULL, /* END OF TABLE */ }, }; @@ -1577,6 +1583,36 @@ static void sheevaplug_reset(int trst, int srst) LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction); } +static void redbee_reset(int trst, int srst) +{ + if (trst == 1) + { + tap_set_state(TAP_RESET); + high_output &= ~nTRST; + } + else if (trst == 0) + { + high_output |= nTRST; + } + + if (srst == 1) + { + high_output &= ~nSRST; + } + else if (srst == 0) + { + high_output |= nSRST; + } + + /* command "set data bits low byte" */ + buffer_write(0x82); + buffer_write(high_output); + buffer_write(high_direction); + LOG_DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, " + "high_direction: 0x%2.2x", trst, srst, high_output, + high_direction); +} + static int ft2232_execute_runtest(struct jtag_command *cmd) { int retval; @@ -2478,6 +2514,73 @@ static int axm0432_jtag_init(void) return ERROR_OK; } +static int redbee_init(void) +{ + uint8_t buf[3]; + uint32_t bytes_written; + + low_output = 0x08; + low_direction = 0x2b; + + /* initialize low byte for jtag */ + /* command "set data bits low byte" */ + buf[0] = 0x80; + /* value (TMS = 1,TCK = 0, TDI = 0, nOE = 0) */ + buf[2] = low_direction; + /* dir (output = 1), TCK/TDI/TMS = out, TDO = in, nOE = out */ + buf[1] = low_output; + LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); + + if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) + || (bytes_written != 3)) + { + LOG_ERROR("couldn't initialize FT2232 with 'redbee' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + nTRST = 0x08; + nTRSTnOE = 0x0; /* No output enable for TRST*/ + nSRST = 0x04; + nSRSTnOE = 0x0; /* No output enable for SRST*/ + + high_output = 0x0; + high_direction = 0x0c; + + enum reset_types jtag_reset_config = jtag_get_reset_config(); + if (jtag_reset_config & RESET_TRST_OPEN_DRAIN) + { + LOG_ERROR("can't set nTRSTOE to push-pull on redbee"); + } + else + { + high_output |= nTRST; + } + + if (jtag_reset_config & RESET_SRST_PUSH_PULL) + { + LOG_ERROR("can't set nSRST to push-pull on redbee"); + } + else + { + high_output |= nSRST; + } + + /* initialize high port */ + buf[0] = 0x82; /* command "set data bits high byte" */ + buf[1] = high_output; /* value */ + buf[2] = high_direction; /* all outputs (xRST and xRSTnOE) */ + LOG_DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]); + + if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) + || (bytes_written != 3)) + { + LOG_ERROR("couldn't initialize FT2232 with 'redbee' layout"); + return ERROR_JTAG_INIT_FAILED; + } + + return ERROR_OK; +} + static int jtagkey_init(void) { uint8_t buf[3]; diff --git a/tcl/board/redbee-econotag.cfg b/tcl/board/redbee-econotag.cfg new file mode 100644 index 0000000..7a02ce0 --- /dev/null +++ b/tcl/board/redbee-econotag.cfg @@ -0,0 +1,8 @@ +source [find target/mc13224v.cfg] + +# The redbee-econotag has an onboard ft2232h with channel A wired +# to the JTAG pins on the mc13224v +# channel B is wired to UART1 +interface ft2232 +ft2232_layout redbee-econotag +ft2232_vid_pid 0x0403 0x6010 commit e4a40d257d6c8fa393929cda50c0a1d777787da2 Author: Mariano Alvira <ma...@de...> Date: Sat Feb 27 22:51:41 2010 -0800 Add target/mc13224v.cfg The MC13224V is a FreeScale ARM7TDMI based IEEE802.15.4 platform for Zigbee and similar low-power wireless applications. Using PIP (Platform In Package) technology, it integrates: an RF balun and matching network; a buck converter (only an external inductor is necessary); 96KB of SRAM; and 128KB of non-volatile memory. It has an integrated bootloader and can boot from a variety of sources: external SPI or I2C non-volatile memory, an image loaded over UART1, or the internal non-volatile memory. The image loaded from one of these sources is executed directly from SRAM starting at location 0x00400000. Open source development code at http://mc1322x.devl.org Signed-off-by: David Brownell <dbr...@us...> diff --git a/tcl/target/mc13224v.cfg b/tcl/target/mc13224v.cfg new file mode 100644 index 0000000..497e376 --- /dev/null +++ b/tcl/target/mc13224v.cfg @@ -0,0 +1,54 @@ +source [find bitsbytes.tcl] +source [find cpu/arm/arm7tdmi.tcl] +source [find memory.tcl] +source [find mmr_helpers.tcl] + +set CHIP_MAKER freescale +set CHIP_FAMILY mc1322x +set CHIP_NAME mc13224 +set N_RAM 1 +set RAM(0,BASE) 0x00400000 +set RAM(0,LEN) 0x18000 +set RAM(0,HUMAN) "internal SRAM" +set RAM(0,TYPE) "ram" +set RAM(0,RWX) $RWX_RWX +set RAM(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY + +# I AM LAZY... I create 1 region for all MMRs. +set N_MMREGS 1 +set MMREGS(0,CHIPSELECT) -1 +set MMREGS(0,BASE) 0x80000000 +set MMREGS(0,LEN) 0x00030000 +set MMREGS(0,HUMAN) "mm-regs" +set MMREGS(0,TYPE) "mmr" +set MMREGS(0,RWX) $RWX_RW +set MMREGS(0,ACCESS_WIDTH) $ACCESS_WIDTH_ANY + +set N_XMEM 0 + +set _CHIPNAME mc13224v +set _CPUTAPID 0x1f1f001d + +jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID + +reset_config srst_only +jtag_ntrst_delay 200 + +# rclk hasn't been working well. This maybe the mc13224v or something else. +#jtag_rclk 2000 +jtag_khz 2000 + +###################### +# Target configuration +###################### + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME + +# Internal sram memory +$_TARGETNAME configure -work-area-phys 0x00408000 \ + -work-area-size 0x1000 \ + -work-area-backup 1 + +# flash support is pending (should be straightforward to implement) +#flash bank mc1322x 0 0 0 0 $_TARGETNAME ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 1 + src/jtag/drivers/ft2232.c | 103 +++++++++++++++++++++++++++++++++++++++++ tcl/board/redbee-econotag.cfg | 8 +++ tcl/target/mc13224v.cfg | 54 +++++++++++++++++++++ 4 files changed, 166 insertions(+), 0 deletions(-) create mode 100644 tcl/board/redbee-econotag.cfg create mode 100644 tcl/target/mc13224v.cfg hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-02-27 09:52:39
|
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 e70d42a727bebc5ae0ce0b1386620d30ea00b05b (commit) via 3ef9beb52cd0ed57ae6d28f7858001bfb68d7e86 (commit) via 8c9b52e8b615198252ab53e1b5c7cf5f314c5ca1 (commit) via a3245bd7cdd2d8c3740c5e8f31efcd78de67837a (commit) from 4a64820f230a267b1f2e36d4be567074e5b8cb76 (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 e70d42a727bebc5ae0ce0b1386620d30ea00b05b Author: David Brownell <dbr...@us...> Date: Sat Feb 27 00:31:35 2010 -0800 new "stellaris recover" command Stellaris chips have a procedure for restoring the chip to what's effectively the "as-manufactured" state, with all the non-volatile memory erased. That includes all flash memory, plus things like the flash protection bits and various control words which can for example disable debugger access. clearly, this can be useful during development. Luminary/TI provides an MS-Windows utility to perform this procedure along with its Stellaris developer kits. Now OpenOCD users will no longer need to use that MS-Windows utility. Signed-off-by: David Brownell <dbr...@us...> diff --git a/NEWS b/NEWS index b39b3a8..56c697f 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,12 @@ Boundary Scan: Target Layer: Flash Layer: + New "stellaris recover" command, implements the procedure + to recover locked devices (restoring non-volatile + state to the factory defaults, including erasing + the flash and its protection bits, and possibly + re-enabling hardware debugging). + Board, Target, and Interface Configuration Scripts: diff --git a/doc/openocd.texi b/doc/openocd.texi index 61e39b2..aa8bed1 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4497,6 +4497,21 @@ flash bank stellaris 0 0 0 0 $_TARGETNAME @end example @end deffn +@deffn Command {stellaris recover bank_id} +Performs the @emph{Recovering a "Locked" Device} procedure to +restore the flash specified by @var{bank_id} and its associated +nonvolatile registers to their factory default values (erased). +This is the only way to remove flash protection or re-enable +debugging if that capability has been disabled. + +Note that the final "power cycle the chip" step in this procedure +must be performed by hand, since OpenOCD can't do it. +@quotation Warning +if more than one Stellaris chip is connected, the procedure is +applied to all of them. +@end quotation +@end deffn + @deffn {Flash Driver} stm32x All members of the STM32 microcontroller family from ST Microelectronics include internal flash and use ARM Cortex M3 cores. diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index 107b1c6..21a0cff 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -1170,13 +1170,79 @@ COMMAND_HANDLER(stellaris_handle_mass_erase_command) return ERROR_OK; } +/** + * Perform the Stellaris "Recovering a 'Locked' Device procedure. + * This performs a mass erase and then restores all nonvolatile registers + * (including USER_* registers and flash lock bits) to their defaults. + * Accordingly, flash can be reprogrammed, and JTAG can be used. + * + * NOTE that DustDevil parts (at least rev A0 silicon) have errata which + * can affect this operation if flash protection has been enabled. + */ +COMMAND_HANDLER(stellaris_handle_recover_command) +{ + struct flash_bank *bank; + int retval; + + retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (retval != ERROR_OK) + return retval; + + /* REVISIT ... it may be worth sanity checking that the AP is + * inactive before we start. ARM documents that switching a DP's + * mode while it's active can cause fault modes that need a power + * cycle to recover. + */ + + /* assert SRST */ + if (!(jtag_get_reset_config() & RESET_HAS_SRST)) { + LOG_ERROR("Can't recover Stellaris flash without SRST"); + return ERROR_FAIL; + } + jtag_add_reset(0, 1); + + for (int i = 0; i < 5; i++) { + retval = dap_to_swd(bank->target); + if (retval != ERROR_OK) + goto done; + + retval = dap_to_jtag(bank->target); + if (retval != ERROR_OK) + goto done; + } + + /* de-assert SRST */ + jtag_add_reset(0, 0); + retval = jtag_execute_queue(); + + /* wait 400+ msec ... OK, "1+ second" is simpler */ + sleep(1); + + /* USER INTERVENTION required for the power cycle + * Restarting OpenOCD is likely needed because of mode switching. + */ + LOG_INFO("USER ACTION: " + "power cycle Stellaris chip, then restart OpenOCD."); + +done: + return retval; +} + static const struct command_registration stellaris_exec_command_handlers[] = { { .name = "mass_erase", .handler = stellaris_handle_mass_erase_command, .mode = COMMAND_EXEC, + .usage = "bank_id", .help = "erase entire device", }, + { + .name = "recover", + .handler = stellaris_handle_recover_command, + .mode = COMMAND_EXEC, + .usage = "bank_id", + .help = "recover locked device", + }, COMMAND_REGISTRATION_DONE }; static const struct command_registration stellaris_command_handlers[] = { commit 3ef9beb52cd0ed57ae6d28f7858001bfb68d7e86 Author: David Brownell <dbr...@us...> Date: Sat Feb 27 00:31:35 2010 -0800 ADIv5 DAP ops switching to JTAG or SWD modes Define two new DAP operations which use the new jtag_add_tms_seq() calls to put the DAP's transport into either SWD or JTAG mode, when the hardware allows. Tested with the Stellaris 'Recovering a "Locked" Device' procedure, which loops five times over both of these. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 41f00ec..6be60af 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -1716,3 +1716,116 @@ DAP_COMMAND_HANDLER(dap_apid_command) return retval; } + +/* + * This represents the bits which must be sent out on TMS/SWDIO to + * switch a DAP implemented using an SWJ-DP module into SWD mode. + * These bits are stored (and transmitted) LSB-first. + * + * See the DAP-Lite specification, section 2.2.5 for information + * about making the debug link select SWD or JTAG. (Similar info + * is in a few other ARM documents.) + */ +static const uint8_t jtag2swd_bitseq[] = { + /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high, + * putting both JTAG and SWD logic into reset state. + */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* Switching sequence enables SWD and disables JTAG + * NOTE: bits in the DP's IDCODE may expose the need for + * an old/deprecated sequence (0xb6 0xed). + */ + 0x9e, 0xe7, + /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high, + * putting both JTAG and SWD logic into reset state. + */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +/** + * Put the debug link into SWD mode, if the target supports it. + * The link's initial mode may be either JTAG (for example, + * with SWJ-DP after reset) or SWD. + * + * @param target Enters SWD mode (if possible). + * + * Note that targets using the JTAG-DP do not support SWD, and that + * some targets which could otherwise support it may have have been + * configured to disable SWD signaling + * + * @return ERROR_OK or else a fault code. + */ +int dap_to_swd(struct target *target) +{ + int retval; + + LOG_DEBUG("Enter SWD mode"); + + /* REVISIT it's nasty to need to make calls to a "jtag" + * subsystem if the link isn't in JTAG mode... + */ + + retval = jtag_add_tms_seq(8 * sizeof(jtag2swd_bitseq), + jtag2swd_bitseq, TAP_INVALID); + if (retval == ERROR_OK) + retval = jtag_execute_queue(); + + /* REVISIT set up the DAP's ops vector for SWD mode. */ + + return retval; +} + +/** + * This represents the bits which must be sent out on TMS/SWDIO to + * switch a DAP implemented using an SWJ-DP module into JTAG mode. + * These bits are stored (and transmitted) LSB-first. + * + * These bits are stored (and transmitted) LSB-first. + */ +static const uint8_t swd2jtag_bitseq[] = { + /* More than 50 TCK/SWCLK cycles with TMS/SWDIO high, + * putting both JTAG and SWD logic into reset state. + */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* Switching equence disables SWD and enables JTAG + * NOTE: bits in the DP's IDCODE can expose the need for + * the old/deprecated sequence (0xae 0xde). + */ + 0x3c, 0xe7, + /* At least 50 TCK/SWCLK cycles with TMS/SWDIO high, + * putting both JTAG and SWD logic into reset state. + * NOTE: some docs say "at least 5". + */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; + +/** Put the debug link into JTAG mode, if the target supports it. + * The link's initial mode may be either SWD or JTAG. + * + * @param target Enters JTAG mode (if possible). + * + * Note that targets implemented with SW-DP do not support JTAG, and + * that some targets which could otherwise support it may have been + * configured to disable JTAG signaling + * + * @return ERROR_OK or else a fault code. + */ +int dap_to_jtag(struct target *target) +{ + int retval; + + LOG_DEBUG("Enter JTAG mode"); + + /* REVISIT it's nasty to need to make calls to a "jtag" + * subsystem if the link isn't in JTAG mode... + */ + + retval = jtag_add_tms_seq(8 * sizeof(swd2jtag_bitseq), + swd2jtag_bitseq, TAP_RESET); + if (retval == ERROR_OK) + retval = jtag_execute_queue(); + + /* REVISIT set up the DAP's ops vector for JTAG mode. */ + + return retval; +} diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 316701e..5c5ca4f 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -235,4 +235,12 @@ DAP_COMMAND_HANDLER(dap_memaccess_command); DAP_COMMAND_HANDLER(dap_apsel_command); DAP_COMMAND_HANDLER(dap_apid_command); +struct target; + +/* Put debug link into SWD mode */ +int dap_to_swd(struct target *target); + +/* Put debug link into JTAG mode */ +int dap_to_jtag(struct target *target); + #endif commit 8c9b52e8b615198252ab53e1b5c7cf5f314c5ca1 Author: David Brownell <dbr...@us...> Date: Sat Feb 27 00:12:38 2010 -0800 ft2232: implement TMS sequence command Implement the new TMS_SEQ command on FT2232 hardware. Also, swap a bogus exit() call with a clean failure return. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c index 4b84fa8..5c6b655 100644 --- a/src/jtag/drivers/ft2232.c +++ b/src/jtag/drivers/ft2232.c @@ -1678,6 +1678,72 @@ static int ft2232_execute_statemove(struct jtag_command *cmd) return retval; } +/** + * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG + * (or SWD) state machine. + */ +static int ft2232_execute_tms(struct jtag_command *cmd) +{ + int retval = ERROR_OK; + unsigned num_bits = cmd->cmd.tms->num_bits; + const uint8_t *bits = cmd->cmd.tms->bits; + unsigned count; + + DEBUG_JTAG_IO("TMS: %d bits", num_bits); + + /* only send the maximum buffer size that FT2232C can handle */ + count = 3 * DIV_ROUND_UP(num_bits, 4); + if (ft2232_buffer_size + 3*count + 1 > FT2232_BUFFER_SIZE) { + if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK) + retval = ERROR_JTAG_QUEUE_FAILED; + + require_send = 0; + first_unsent = cmd; + } + + /* Shift out in batches of at most 6 bits; there's a report of an + * FT2232 bug in this area, where shifting exactly 7 bits can make + * problems with TMS signaling for the last clock cycle: + * + * http://developer.intra2net.com/mailarchive/html/ + * libftdi/2009/msg00292.html + * + * Command 0x4b is: "Clock Data to TMS/CS Pin (no Read)" + * + * Note that pathmoves in JTAG are not often seven bits, so that + * isn't a particularly likely situation outside of "special" + * signaling such as switching between JTAG and SWD modes. + */ + while (num_bits) { + if (num_bits <= 6) { + buffer_write(0x4b); + buffer_write(num_bits - 1); + buffer_write(*bits & 0x3f); + break; + } + + /* Yes, this is lazy ... we COULD shift out more data + * bits per operation, but doing it in nybbles is easy + */ + buffer_write(0x4b); + buffer_write(3); + buffer_write(*bits & 0xf); + num_bits -= 4; + + count = (num_bits > 4) ? 4 : num_bits; + + buffer_write(0x4b); + buffer_write(count - 1); + buffer_write((*bits >> 4) & 0xf); + num_bits -= count; + + bits++; + } + + require_send = 1; + return retval; +} + static int ft2232_execute_pathmove(struct jtag_command *cmd) { int predicted_size = 0; @@ -1830,7 +1896,6 @@ static int ft2232_execute_stableclocks(struct jtag_command *cmd) static int ft2232_execute_command(struct jtag_command *cmd) { int retval; - retval = ERROR_OK; switch (cmd->type) { @@ -1841,9 +1906,13 @@ static int ft2232_execute_command(struct jtag_command *cmd) case JTAG_SCAN: retval = ft2232_execute_scan(cmd); break; case JTAG_SLEEP: retval = ft2232_execute_sleep(cmd); break; case JTAG_STABLECLOCKS: retval = ft2232_execute_stableclocks(cmd); break; + case JTAG_TMS: + retval = ft2232_execute_tms(cmd); + break; default: LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); + retval = ERROR_JTAG_QUEUE_FAILED; + break; } return retval; } @@ -4108,6 +4177,7 @@ static const struct command_registration ft2232_command_handlers[] = { struct jtag_interface ft2232_interface = { .name = "ft2232", + .supported = DEBUG_CAP_TMS_SEQ, .commands = ft2232_command_handlers, .init = ft2232_init, commit a3245bd7cdd2d8c3740c5e8f31efcd78de67837a Author: David Brownell <dbr...@us...> Date: Sat Feb 27 00:12:38 2010 -0800 interface: define TMS sequence command For support of SWD we need to be able to clock out special bit sequences over TMS or SWDIO. Create this as a generic operation, not yet called by anything, which is split as usual into: - upper level abstraction ... here, jtag_add_tms_seq(); - midlayer implementation logic hooking that to the lowlevel code; - lowlevel minidriver operation ... here, interface_add_tms_seq(); - message type for request queue, here JTAG_TMS. This is done slightly differently than other operations: there's a flag saying whether the interface driver supports this request. (In fact a flag *word* so upper layers can learn about other capabilities too ... for example, supporting SWD operations.) That approach (flag) lets this method *eventually* be used to eliminate pathmove() and statemove() support from most adapter drivers, by moving all that logic into the mid-layer and increasing uniformity between the various drivers. (Which will in turn reduce subtle bugginess.) Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/jtag/commands.h b/src/jtag/commands.h index b10b545..692eee4 100644 --- a/src/jtag/commands.h +++ b/src/jtag/commands.h @@ -99,18 +99,38 @@ struct sleep_command { }; /** + * Encapsulates a series of bits to be clocked out, affecting state + * and mode of the interface. + * + * In JTAG mode these are clocked out on TMS, using TCK. They may be + * used for link resets, transitioning between JTAG and SWD modes, or + * to implement JTAG state machine transitions (implementing pathmove + * or statemove operations). + * + * In SWD mode these are clocked out on SWDIO, using SWCLK, and are + * used for link resets and transitioning between SWD and JTAG modes. + */ +struct tms_command { + /** How many bits should be clocked out. */ + unsigned num_bits; + /** The bits to clock out; the LSB is bit 0 of bits[0]. */ + const uint8_t *bits; +}; + +/** * Defines a container type that hold a pointer to a JTAG command * structure of any defined type. */ union jtag_command_container { - struct scan_command* scan; - struct statemove_command* statemove; - struct pathmove_command* pathmove; - struct runtest_command* runtest; - struct stableclocks_command* stableclocks; - struct reset_command* reset; - struct end_state_command* end_state; - struct sleep_command* sleep; + struct scan_command *scan; + struct statemove_command *statemove; + struct pathmove_command *pathmove; + struct runtest_command *runtest; + struct stableclocks_command *stableclocks; + struct reset_command *reset; + struct end_state_command *end_state; + struct sleep_command *sleep; + struct tms_command *tms; }; /** @@ -124,7 +144,8 @@ enum jtag_command_type { JTAG_RESET = 4, JTAG_PATHMOVE = 6, JTAG_SLEEP = 7, - JTAG_STABLECLOCKS = 8 + JTAG_STABLECLOCKS = 8, + JTAG_TMS = 9, }; struct jtag_command { diff --git a/src/jtag/core.c b/src/jtag/core.c index 4f517c0..7f417b7 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -488,6 +488,35 @@ void jtag_add_tlr(void) jtag_notify_event(JTAG_TRST_ASSERTED); } +/** + * If supported by the underlying adapter, this clocks a raw bit sequence + * onto TMS for switching betwen JTAG and SWD modes. + * + * DO NOT use this to bypass the integrity checks and logging provided + * by the jtag_add_pathmove() and jtag_add_statemove() calls. + * + * @param nbits How many bits to clock out. + * @param seq The bit sequence. The LSB is bit 0 of seq[0]. + * @param state The JTAG tap state to record on completion. Use + * TAP_INVALID to represent being in in SWD mode. + * + * @todo Update naming conventions to stop assuming everything is JTAG. + */ +int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state) +{ + int retval; + + if (!(jtag->supported & DEBUG_CAP_TMS_SEQ)) + return ERROR_JTAG_NOT_IMPLEMENTED; + + jtag_checks(); + cmd_queue_cur_state = state; + + retval = interface_add_tms_seq(nbits, seq); + jtag_set_error(retval); + return retval; +} + void jtag_add_pathmove(int num_states, const tap_state_t *path) { tap_state_t cur_state = cmd_queue_cur_state; diff --git a/src/jtag/drivers/driver.c b/src/jtag/drivers/driver.c index 45c5d10..14efe96 100644 --- a/src/jtag/drivers/driver.c +++ b/src/jtag/drivers/driver.c @@ -388,6 +388,31 @@ int interface_jtag_add_tlr(void) return ERROR_OK; } +int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq) +{ + struct jtag_command *cmd; + + cmd = cmd_queue_alloc(sizeof(struct jtag_command)); + if (cmd == NULL) + return ERROR_FAIL; + + cmd->type = JTAG_TMS; + cmd->cmd.tms = cmd_queue_alloc(sizeof(*cmd->cmd.tms)); + if (!cmd->cmd.tms) + return ERROR_FAIL; + + /* copy the bits; our caller doesn't guarantee they'll persist */ + cmd->cmd.tms->num_bits = num_bits; + cmd->cmd.tms->bits = buf_cpy(seq, + cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits); + if (!cmd->cmd.tms->bits) + return ERROR_FAIL; + + jtag_queue_command(cmd); + + return ERROR_OK; +} + int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) { /* allocate memory for a new list member */ diff --git a/src/jtag/interface.h b/src/jtag/interface.h index a264d69..0d47404 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -184,11 +184,29 @@ static inline tap_state_t jtag_debug_state_machine(const void *tms_buf, } #endif // _DEBUG_JTAG_IO_ +/** + * Represents a driver for a debugging interface. + * + * @todo Rename; perhaps "debug_driver". This isn't an interface, + * it's a driver! Also, not all drivers support JTAG. + * + * @todo We need a per-instance structure too, and changes to pass + * that structure to the driver. Instances can for example be in + * either SWD or JTAG modes. This will help remove globals, and + * eventually to cope with systems which have more than one such + * debugging interface. + */ struct jtag_interface { /// The name of the JTAG interface driver. char* name; /** + * Bit vector listing capabilities exposed by this driver. + */ + unsigned supported; +#define DEBUG_CAP_TMS_SEQ (1 << 0) + + /** * Execute queued commands. * @returns ERROR_OK on success, or an error code on failure. */ diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index 0555754..7e5dc10 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -575,6 +575,8 @@ tap_state_t jtag_get_end_state(void); void jtag_add_sleep(uint32_t us); +int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state t); + /** * Function jtag_add_clocks * first checks that the state in which the clocks are to be issued is @@ -693,7 +695,7 @@ int jtag_error_clear(void); /** * Return true if it's safe for a background polling task to access the * JTAG scan chain. Polling may be explicitly disallowed, and is also - * unsafe while nTRST is active or the JTAG clock is gated off., + * unsafe while nTRST is active or the JTAG clock is gated off. */ bool is_jtag_poll_safe(void); diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h index 2109c75..5caec58 100644 --- a/src/jtag/minidriver.h +++ b/src/jtag/minidriver.h @@ -67,6 +67,8 @@ int interface_jtag_add_tlr(void); int interface_jtag_add_pathmove(int num_states, const tap_state_t* path); int interface_jtag_add_runtest(int num_cycles, tap_state_t endstate); +int interface_add_tms_seq(unsigned num_bits, const uint8_t *bits); + /** * This drives the actual srst and trst pins. srst will always be 0 * if jtag_reset_config & RESET_SRST_PULLS_TRST != 0 and ditto for diff --git a/src/jtag/minidummy/minidummy.c b/src/jtag/minidummy/minidummy.c index 9c608cd..6410c2d 100644 --- a/src/jtag/minidummy/minidummy.c +++ b/src/jtag/minidummy/minidummy.c @@ -147,6 +147,13 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) return ERROR_OK; } +int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq) +{ + /* synchronously do the operation here */ + + return ERROR_OK; +} + void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count) { int i; diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index d920c30..e21104c 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -804,7 +804,16 @@ int interface_jtag_add_pathmove(int num_states, const tap_state_t *path) return ERROR_OK; } - +int interface_add_tms_seq(unsigned num_bits, const uint8_t *seq) +{ + /* FIXME just implement this, like pathmove but without + * JTAG-specific state transition checking. Then update + * zy1000_interface to report that it's supported. + * + * Eventually interface_jtag_add_pathmove() could vanish. + */ + return ERROR_JTAG_NOT_IMPLEMENTED; +} void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count) { ----------------------------------------------------------------------- Summary of changes: NEWS | 6 ++ doc/openocd.texi | 15 +++++ src/flash/nor/stellaris.c | 66 +++++++++++++++++++++++ src/jtag/commands.h | 39 +++++++++++--- src/jtag/core.c | 29 ++++++++++ src/jtag/drivers/driver.c | 25 +++++++++ src/jtag/drivers/ft2232.c | 74 +++++++++++++++++++++++++- src/jtag/interface.h | 18 ++++++ src/jtag/jtag.h | 4 +- src/jtag/minidriver.h | 2 + src/jtag/minidummy/minidummy.c | 7 +++ src/jtag/zy1000/zy1000.c | 11 ++++- src/target/arm_adi_v5.c | 113 ++++++++++++++++++++++++++++++++++++++++ src/target/arm_adi_v5.h | 8 +++ 14 files changed, 404 insertions(+), 13 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-02-25 09:14:21
|
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 4a64820f230a267b1f2e36d4be567074e5b8cb76 (commit) via 79010bf3dfad01ff11b37a9a6c79452a604c596d (commit) via 7abe9f38b2321b00b240fb7901dc408106fb07f8 (commit) from 75067c40424f0e3349f445ed4ec43476a89973da (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 4a64820f230a267b1f2e36d4be567074e5b8cb76 Author: Mariano Alvira <ma...@de...> Date: Thu Feb 25 00:01:55 2010 -0800 ft2232: add a mechanism to specify channel in layout structs FT2232-family chips have two or more MPSSE modules. FTDI documentation calls these channels. JTAG adapter drivers thus need to be able to choose which channel to use. (For example, one channel may connect to a board's microcontroller, while another connects to a CPLD.) Since each channel has its own USB interface, libftdi (somewhat confusingly) identifies channels using INTERFACE_* symbols. Most boards use INTERFACE_A for JTAG, which is the default in OpenOCD. But some wire up a different one. Note that there are two facets of what makes a wiring "layout": - The mapping between debug signals map and channel signals ... embedded in C functions. - Label used in Tcl configuration scripts ... part of the "layout" structure. By letting the channel be part of the layout struct, we permit sharing the C functions between Tcl-visible layouts, when those signal mappings are reused. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c index 5042a22..4b84fa8 100644 --- a/src/jtag/drivers/ft2232.c +++ b/src/jtag/drivers/ft2232.c @@ -145,6 +145,7 @@ struct ft2232_layout { int (*init)(void); void (*reset)(int trst, int srst); void (*blink)(void); + int channel; }; /* init procedures for supported layouts */ @@ -2062,7 +2063,7 @@ static int ft2232_purge_ftd2xx(void) #endif /* BUILD_FT2232_FTD2XX == 1 */ #if BUILD_FT2232_LIBFTDI == 1 -static int ft2232_init_libftdi(uint16_t vid, uint16_t pid, int more, int* try_more) +static int ft2232_init_libftdi(uint16_t vid, uint16_t pid, int more, int* try_more, int channel) { uint8_t latency_timer; @@ -2072,7 +2073,10 @@ static int ft2232_init_libftdi(uint16_t vid, uint16_t pid, int more, int* try_mo if (ftdi_init(&ftdic) < 0) return ERROR_JTAG_INIT_FAILED; - if (ftdi_set_interface(&ftdic, INTERFACE_A) < 0) + /* default to INTERFACE_A */ + if(channel == INTERFACE_ANY) { channel = INTERFACE_A; } + + if (ftdi_set_interface(&ftdic, channel) < 0) { LOG_ERROR("unable to select FT2232 channel A: %s", ftdic.error_str); return ERROR_JTAG_INIT_FAILED; @@ -2197,7 +2201,7 @@ static int ft2232_init(void) more, &try_more); #elif BUILD_FT2232_LIBFTDI == 1 retval = ft2232_init_libftdi(ft2232_vid[i], ft2232_pid[i], - more, &try_more); + more, &try_more, cur_layout->channel); #endif if (retval >= 0) break; commit 79010bf3dfad01ff11b37a9a6c79452a604c596d Author: David Brownell <dbr...@us...> Date: Wed Feb 24 23:46:46 2010 -0800 ARM ADIv5 doxygen and cleanup Add doxygen for mem_ap_read_buf_u{8,16,32}() calls, and shrink a few overlong lines. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 435d659..41f00ec 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -866,14 +866,16 @@ int mem_ap_write_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, return retval; } -/********************************************************************************* -* * -* mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address) * -* * -* Read block fast in target order (little endian) into a buffer * -* * -**********************************************************************************/ -int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address) +/** + * Synchronously read a block of 32-bit words into a buffer + * @param swjdp The DAP connected to the MEM-AP. + * @param buffer where the words will be stored (in host byte order). + * @param count How many words to read. + * @param address Memory address from which to read words; all the + * words must be readable by the currently selected MEM-AP. + */ +int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, + int count, uint32_t address) { int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK; uint32_t adr = address; @@ -884,8 +886,12 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, while (wcount > 0) { - /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/ - blocksize = max_tar_block_size(swjdp->tar_autoincr_block, address); + /* Adjust to read blocks within boundaries aligned to the + * TAR autoincrement size (at least 2^10). Autoincrement + * mode avoids an extra per-word roundtrip to update TAR. + */ + blocksize = max_tar_block_size(swjdp->tar_autoincr_block, + address); if (wcount < blocksize) blocksize = wcount; @@ -893,7 +899,8 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, if (blocksize == 0) blocksize = 1; - dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, address); + dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_SINGLE, + address); /* Scan out first read */ adi_jtag_dp_scan(swjdp, JTAG_DP_APACC, AP_REG_DRW, @@ -928,7 +935,8 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, if (errorcount > 1) { - LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count); + LOG_WARNING("Block read error address 0x%" PRIx32 + ", count 0x%x", address, count); return ERROR_JTAG_DEVICE_ERROR; } } @@ -944,7 +952,8 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, for (i = 0; i < 4; i++) { - *((uint8_t*)pBuffer) = (data >> 8 * (adr & 0x3)); + *((uint8_t*)pBuffer) = + (data >> 8 * (adr & 0x3)); pBuffer++; adr++; } @@ -1005,7 +1014,16 @@ static int mem_ap_read_buf_packed_u16(struct swjdp_common *swjdp, return retval; } -int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address) +/** + * Synchronously read a block of 16-bit halfwords into a buffer + * @param swjdp The DAP connected to the MEM-AP. + * @param buffer where the halfwords will be stored (in host byte order). + * @param count How many halfwords to read. + * @param address Memory address from which to read words; all the + * words must be readable by the currently selected MEM-AP. + */ +int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, + int count, uint32_t address) { uint32_t invalue, i; int retval = ERROR_OK; @@ -1094,7 +1112,16 @@ static int mem_ap_read_buf_packed_u8(struct swjdp_common *swjdp, return retval; } -int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t address) +/** + * Synchronously read a block of bytes into a buffer + * @param swjdp The DAP connected to the MEM-AP. + * @param buffer where the bytes will be stored. + * @param count How many bytes to read. + * @param address Memory address from which to read data; all the + * data must be readable by the currently selected MEM-AP. + */ +int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, + int count, uint32_t address) { uint32_t invalue; int retval = ERROR_OK; commit 7abe9f38b2321b00b240fb7901dc408106fb07f8 Author: Hans Peter Mortensn <hp...@sp...> Date: Wed Feb 24 23:35:12 2010 -0800 AVR flash: handle AT90CAN128 chips I have successfully programmed the AT90CAN128, based on the mega128 Â with some small modifications. [ dbr...@us...: patch cleanup ] Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c index c072419..5b40ad7 100644 --- a/src/flash/nor/avrf.c +++ b/src/flash/nor/avrf.c @@ -52,8 +52,11 @@ struct avrf_type avft_chips_info[] = { -// name, chip_id, flash_page_size, flash_page_num, eeprom_page_size, eeprom_page_num - {"atmega128", 0x9702, 256, 512, 8, 512}, +/* name, chip_id, flash_page_size, flash_page_num, + * eeprom_page_size, eeprom_page_num + */ + {"atmega128", 0x9702, 256, 512, 8, 512}, + {"at90can128", 0x9781, 256, 512, 8, 512}, }; int avr_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out); @@ -200,8 +203,27 @@ FLASH_BANK_COMMAND_HANDLER(avrf_flash_bank_command) static int avrf_erase(struct flash_bank *bank, int first, int last) { - LOG_INFO("%s", __FUNCTION__); - return ERROR_OK; + struct target *target = bank->target; + struct avr_common *avr = target->arch_info; + int status; + + LOG_DEBUG("%s", __FUNCTION__); + + if (target->state != TARGET_HALTED) + { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + status = avr_jtagprg_enterprogmode(avr); + if (status != ERROR_OK) + return status; + + status = avr_jtagprg_chiperase(avr); + if (status != ERROR_OK) + return status; + + return avr_jtagprg_leaveprogmode(avr); } static int avrf_protect(struct flash_bank *bank, int set, int first, int last) ----------------------------------------------------------------------- Summary of changes: src/flash/nor/avrf.c | 30 ++++++++++++++++++++--- src/jtag/drivers/ft2232.c | 10 +++++-- src/target/arm_adi_v5.c | 57 +++++++++++++++++++++++++++++++++------------ 3 files changed, 75 insertions(+), 22 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-02-24 09:55:21
|
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 75067c40424f0e3349f445ed4ec43476a89973da (commit) from faef631a4d1429f48c34da13d446dcd64d1523bf (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 75067c40424f0e3349f445ed4ec43476a89973da Author: David Brownell <dbr...@us...> Date: Tue Feb 23 23:36:42 2010 -0800 ARM ADIv5: rename more JTAG-specific routines Highlight more of the internal JTAG-specific utilities, so it's easier to identify code needing changes to become transport-neutral. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index d30dd50..435d659 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -185,14 +185,14 @@ static int adi_jtag_dp_scan_u32(struct swjdp_common *swjdp, /** * Utility to write AP registers. */ -static inline int ap_write_check(struct swjdp_common *dap, +static inline int adi_jtag_ap_write_check(struct swjdp_common *dap, uint8_t reg_addr, uint8_t *outvalue) { return adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg_addr, DPAP_WRITE, outvalue, NULL, NULL); } -static int scan_inout_check_u32(struct swjdp_common *swjdp, +static int adi_jtag_scan_inout_check_u32(struct swjdp_common *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint32_t outvalue, uint32_t *invalue) { @@ -222,7 +222,7 @@ int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) #if 0 /* Danger!!!! BROKEN!!!! */ - scan_inout_check_u32(swjdp, JTAG_DP_DPACC, + adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); /* Danger!!!! BROKEN!!!! Why will jtag_execute_queue() fail here???? R956 introduced the check on return value here and now Michael Schwingen reports @@ -240,7 +240,7 @@ int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) /* Post CTRL/STAT read; discard any previous posted read value * but collect its ACK status. */ - scan_inout_check_u32(swjdp, JTAG_DP_DPACC, + adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); if ((retval = jtag_execute_queue()) != ERROR_OK) return retval; @@ -275,7 +275,7 @@ int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) return ERROR_JTAG_DEVICE_ERROR; } - scan_inout_check_u32(swjdp, JTAG_DP_DPACC, + adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); if ((retval = jtag_execute_queue()) != ERROR_OK) return retval; @@ -317,11 +317,11 @@ int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) LOG_ERROR("JTAG-DP STICKY ERROR"); /* Clear Sticky Error Bits */ - scan_inout_check_u32(swjdp, JTAG_DP_DPACC, + adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, DP_CTRL_STAT, DPAP_WRITE, swjdp->dp_ctrl_stat | SSTICKYORUN | SSTICKYERR, NULL); - scan_inout_check_u32(swjdp, JTAG_DP_DPACC, + adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); if ((retval = jtag_execute_queue()) != ERROR_OK) return retval; @@ -353,14 +353,14 @@ int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) static int dap_dp_write_reg(struct swjdp_common *swjdp, uint32_t value, uint8_t reg_addr) { - return scan_inout_check_u32(swjdp, JTAG_DP_DPACC, + return adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, reg_addr, DPAP_WRITE, value, NULL); } static int dap_dp_read_reg(struct swjdp_common *swjdp, uint32_t *value, uint8_t reg_addr) { - return scan_inout_check_u32(swjdp, JTAG_DP_DPACC, + return adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_DPACC, reg_addr, DPAP_READ, 0, value); } @@ -412,7 +412,7 @@ static int dap_ap_write_reg(struct swjdp_common *swjdp, if (retval != ERROR_OK) return retval; - return ap_write_check(swjdp, reg_addr, out_value_buf); + return adi_jtag_ap_write_check(swjdp, reg_addr, out_value_buf); } /** @@ -452,7 +452,7 @@ int dap_ap_read_reg_u32(struct swjdp_common *swjdp, if (retval != ERROR_OK) return retval; - return scan_inout_check_u32(swjdp, JTAG_DP_APACC, reg_addr, + return adi_jtag_scan_inout_check_u32(swjdp, JTAG_DP_APACC, reg_addr, DPAP_READ, 0, value); } ----------------------------------------------------------------------- Summary of changes: src/target/arm_adi_v5.c | 22 +++++++++++----------- 1 files changed, 11 insertions(+), 11 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: Øyvind H. <go...@us...> - 2010-02-22 10:31:16
|
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 faef631a4d1429f48c34da13d446dcd64d1523bf (commit) via 1f5883ea56cb058221f5731359da3d66838077e0 (commit) from 90efc404f3cb9c3f6e7fdb8a2c22fb3e72e9072f (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 faef631a4d1429f48c34da13d446dcd64d1523bf Author: Ãyvind Harboe <oyv...@zy...> Date: Tue Feb 9 14:26:57 2010 +0100 arm11: improve performance using minidriver hook zy1000 performance for GDB load went from 100kBytes/s to 300kBytes/s @ 8 MHz by implementing the inner loop of unack arm11 memory writes directly on top of the hw fifo. Profiling info: 78.57 0.77 0.77 arm11_run_instr_data_to_core_noack_inner 5.10 0.82 0.05 memcpy 4.08 0.86 0.04 jtag_tap_next_enabled 3.06 0.89 0.03 gdb_input Signed-off-by: Ãyvind Harboe <oyv...@zy...> diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index da5aa36..d920c30 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -845,11 +845,73 @@ void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, } -int arm11_run_instr_data_to_core_noack_inner_default(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count); -int arm11_run_instr_data_to_core_noack_inner(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count) +int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count) { - return arm11_run_instr_data_to_core_noack_inner_default(arm11, opcode, data, count); +#if 0 + int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count); + return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count); +#else + static const int bits[] = {32, 2}; + uint32_t values[] = {0, 0}; + + /* FIX!!!!!! the target_write_memory() API started this nasty problem + * with unaligned uint32_t * pointers... */ + const uint8_t *t = (const uint8_t *)data; + + while (count--) + { + values[0] = *t++; + values[0] |= (*t++<<8); + values[0] |= (*t++<<16); + values[0] |= (*t++<<24); + + if (count > 0) + { + jtag_add_dr_out(tap, + 2, + bits, + values, + TAP_DRPAUSE); + +#if 1 + /* copy & paste from arm11_dbgtap.c */ + //TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT + + waitIdle(); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 1); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x28, 0); + waitIdle(); + ZY1000_POKE(ZY1000_JTAG_BASE + 0x20, TAP_DRSHIFT); +#else + static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] = + { + TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT + }; + + jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), + arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay); +#endif + } else + { + /* This will happen on the last iteration updating the current tap state + * so we don't have to track it during the common code path */ + jtag_add_dr_out(tap, + 2, + bits, + values, + TAP_IDLE); + } + } + + return jtag_execute_queue(); +#endif } commit 1f5883ea56cb058221f5731359da3d66838077e0 Author: Ãyvind Harboe <oyv...@zy...> Date: Tue Feb 9 09:55:56 2010 +0100 arm11: allow minidrivers to implement inner loop of memory writes This allows minidrivers to e.g. hardware accelerate memory writes. Same trick as is used for arm7/9 dcc writes. Added error propagation for memory transfer failures in code rearrangement. Also the JTAG end state is not updated until after the memory write run is complete. Signed-off-by: Ãyvind Harboe <oyv...@zy...> diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index ef4f482..da5aa36 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -845,6 +845,14 @@ void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, } +int arm11_run_instr_data_to_core_noack_inner_default(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count); + +int arm11_run_instr_data_to_core_noack_inner(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count) +{ + return arm11_run_instr_data_to_core_noack_inner_default(arm11, opcode, data, count); +} + + static const struct command_registration zy1000_commands[] = { { .name = "power", diff --git a/src/target/arm11_dbgtap.c b/src/target/arm11_dbgtap.c index 6d132a7..b8388c8 100644 --- a/src/target/arm11_dbgtap.c +++ b/src/target/arm11_dbgtap.c @@ -569,43 +569,31 @@ static const tap_state_t arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay[] = TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT }; - - -/** Execute one instruction via ITR repeatedly while - * passing data to the core via DTR on each execution. - * - * Caller guarantees that processor is in debug state, that DSCR_ITR_EN - * is set, the ITR Ready flag is set (as seen on the previous entry to - * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. - * - * No Ready check during transmission. - * - * The executed instruction \em must read data from DTR. - * - * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block - * - * \param arm11 Target state variable. - * \param opcode ARM opcode - * \param data Pointer to the data words to be passed to the core - * \param count Number of data words and instruction repetitions - * +/* This inner loop can be implemented by the minidriver, oftentimes in hardware... The + * minidriver can call the default implementation as a fallback or implement it + * from scratch. */ -int arm11_run_instr_data_to_core_noack(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count) +int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count) { - arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); + struct scan_field chain5_fields[3]; - arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE); + chain5_fields[0].tap = tap; + chain5_fields[0].num_bits = 32; + chain5_fields[0].out_value = NULL; /*&Data*/ + chain5_fields[0].in_value = NULL; - arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT); + chain5_fields[1].tap = tap; + chain5_fields[1].num_bits = 1; + chain5_fields[1].out_value = NULL; + chain5_fields[1].in_value = NULL; /*&Ready*/ - struct scan_field chain5_fields[3]; - - arm11_setup_field(arm11, 32, NULL/*&Data*/, NULL, chain5_fields + 0); - arm11_setup_field(arm11, 1, NULL, NULL /*&Ready*/, chain5_fields + 1); - arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2); + chain5_fields[2].tap = tap; + chain5_fields[2].num_bits = 1; + chain5_fields[2].out_value = NULL; + chain5_fields[2].in_value = NULL; uint8_t *Readies; - unsigned readiesNum = count + 1; + unsigned readiesNum = count; unsigned bytes = sizeof(*Readies)*readiesNum; Readies = (uint8_t *) malloc(bytes); @@ -616,31 +604,22 @@ int arm11_run_instr_data_to_core_noack(struct arm11_common * arm11, uint32_t opc } uint8_t * ReadyPos = Readies; - while (count--) { chain5_fields[0].out_value = (void *)(data++); chain5_fields[1].in_value = ReadyPos++; - if (count) + if (count > 0) { - jtag_add_dr_scan(ARRAY_SIZE(chain5_fields), chain5_fields, jtag_set_end_state(TAP_DRPAUSE)); + jtag_add_dr_scan(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE); jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay); - } - else + } else { - jtag_add_dr_scan(ARRAY_SIZE(chain5_fields), chain5_fields, jtag_set_end_state(TAP_IDLE)); + jtag_add_dr_scan(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_IDLE); } } - arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); - - chain5_fields[0].out_value = 0; - chain5_fields[1].in_value = ReadyPos++; - - arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE); - int retval = jtag_execute_queue(); if (retval == ERROR_OK) { @@ -655,16 +634,84 @@ int arm11_run_instr_data_to_core_noack(struct arm11_common * arm11, uint32_t opc } if (error_count > 0 ) + { LOG_ERROR("%u words out of %u not transferred", error_count, readiesNum); - + retval = ERROR_FAIL; + } } - free(Readies); return retval; } +int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count); + +#ifndef HAVE_JTAG_MINIDRIVER_H +int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count) +{ + return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count); +} +#endif + +/** Execute one instruction via ITR repeatedly while + * passing data to the core via DTR on each execution. + * + * Caller guarantees that processor is in debug state, that DSCR_ITR_EN + * is set, the ITR Ready flag is set (as seen on the previous entry to + * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. + * + * No Ready check during transmission. + * + * The executed instruction \em must read data from DTR. + * + * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block + * + * \param arm11 Target state variable. + * \param opcode ARM opcode + * \param data Pointer to the data words to be passed to the core + * \param count Number of data words and instruction repetitions + * + */ +int arm11_run_instr_data_to_core_noack(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count) +{ + arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); + + arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE); + + arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT); + + int retval = arm11_run_instr_data_to_core_noack_inner(arm11->arm.target->tap, opcode, data, count); + + if (retval != ERROR_FAIL) + return retval; + + arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); + + struct scan_field chain5_fields[3]; + + arm11_setup_field(arm11, 32, NULL/*&Data*/, NULL, chain5_fields + 0); + arm11_setup_field(arm11, 1, NULL, NULL /*&Ready*/, chain5_fields + 1); + arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2); + + uint8_t ready_flag; + chain5_fields[1].in_value = &ready_flag; + + arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE); + + retval = jtag_execute_queue(); + if (retval == ERROR_OK) + { + if (ready_flag != 1) + { + LOG_ERROR("last word not transferred"); + retval = ERROR_FAIL; + } + } + + return retval; +} + /** Execute an instruction via ITR while handing data into the core via DTR. * ----------------------------------------------------------------------- Summary of changes: src/jtag/zy1000/zy1000.c | 70 +++++++++++++++++++++++ src/target/arm11_dbgtap.c | 137 ++++++++++++++++++++++++++++++--------------- 2 files changed, 162 insertions(+), 45 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: Øyvind H. <go...@us...> - 2010-02-22 08:00:32
|
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 90efc404f3cb9c3f6e7fdb8a2c22fb3e72e9072f (commit) from c21c740a895438832ed7e945ee4943da3eb733f9 (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 90efc404f3cb9c3f6e7fdb8a2c22fb3e72e9072f Author: Ãyvind Harboe <oyv...@zy...> Date: Mon Feb 8 15:40:53 2010 +0100 zy1000: jtag_add_dr_scan() performance improvement Reduce overhead in jtag_add_dr_scan() a bit. Signed-off-by: Ãyvind Harboe <oyv...@zy...> diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index 2c205b7..ef4f482 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -650,22 +650,29 @@ int interface_jtag_add_dr_scan(int num_fields, const struct scan_field *fields, for (j = 0; j < num_fields; j++) { + /* Find a range of fields to write to this tap */ if (tap == fields[j].tap) { found = 1; + int i; + for (i = j + 1; i < num_fields; i++) + { + if (tap != fields[j].tap) + { + break; + } + } + + scanFields(i - j, fields + j, TAP_DRSHIFT, pause); - scanFields(1, fields+j, TAP_DRSHIFT, pause); + j = i; } } + if (!found) { - struct scan_field tmp; - /* program the scan field to 1 bit length, and ignore it's value */ - tmp.num_bits = 1; - tmp.out_value = NULL; - tmp.in_value = NULL; - - scanFields(1, &tmp, TAP_DRSHIFT, pause); + /* Shift out a 0 for disabled tap's */ + shiftValueInner(TAP_DRSHIFT, pause?TAP_DRPAUSE:TAP_DRSHIFT, 1, 0); } else { ----------------------------------------------------------------------- Summary of changes: src/jtag/zy1000/zy1000.c | 23 +++++++++++++++-------- 1 files changed, 15 insertions(+), 8 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: David B. <dbr...@us...> - 2010-02-22 02:52:30
|
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 c21c740a895438832ed7e945ee4943da3eb733f9 (commit) via dc342f45f6c8ec02431495863687b3638f1646d5 (commit) via c8ea748dc22660dad934537384d35903dfcc492e (commit) via 3b68a708c2b039d9b091608eccb2206725742a47 (commit) via ecff73043c1ddcc97d4d1ea1c87f251a850b22d4 (commit) via 39cfe6279616a69b858ddd3493d61ed7133ff081 (commit) via a97bb67543eacde38f093610982812f714e7a050 (commit) via 249263d29da11b0ec981c2e0d520cd7dcf08939b (commit) via 1aac72d24339380f6e98c50dec4c96ab30537749 (commit) via a299371a9ec109da3851cb43aed3e9157d095358 (commit) via 27c068c1f82423a2492899d1632caaa6f8261810 (commit) via ce1feaa7322affd3b979c9fe93dd8f7462ea9eca (commit) from b853b9dbc0ba3d68a501d8badc4491f8108cd11b (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 c21c740a895438832ed7e945ee4943da3eb733f9 Author: David Brownell <dbr...@us...> Date: Sun Feb 21 17:19:08 2010 -0800 ft2232 table init cleanup Use labeled initializers in the table of layouts instead of positional ones. This ls cleaner and less error prone, plus it simplifies patches which add members to these structure. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/jtag/drivers/ft2232.c b/src/jtag/drivers/ft2232.c index 82132d3..5042a22 100644 --- a/src/jtag/drivers/ft2232.c +++ b/src/jtag/drivers/ft2232.c @@ -185,25 +185,84 @@ static void ktlink_blink(void); static const struct ft2232_layout ft2232_layouts[] = { - { "usbjtag", usbjtag_init, usbjtag_reset, NULL }, - { "jtagkey", jtagkey_init, jtagkey_reset, NULL }, - { "jtagkey_prototype_v1", jtagkey_init, jtagkey_reset, NULL }, - { "oocdlink", jtagkey_init, jtagkey_reset, NULL }, - { "signalyzer", usbjtag_init, usbjtag_reset, NULL }, - { "evb_lm3s811", usbjtag_init, usbjtag_reset, NULL }, - { "luminary_icdi", usbjtag_init, usbjtag_reset, NULL }, - { "olimex-jtag", olimex_jtag_init, olimex_jtag_reset, olimex_jtag_blink }, - { "flyswatter", flyswatter_init, flyswatter_reset, flyswatter_jtag_blink }, - { "turtelizer2", turtle_init, turtle_reset, turtle_jtag_blink }, - { "comstick", comstick_init, comstick_reset, NULL }, - { "stm32stick", stm32stick_init, stm32stick_reset, NULL }, - { "axm0432_jtag", axm0432_jtag_init, axm0432_jtag_reset, NULL }, - { "sheevaplug", sheevaplug_init, sheevaplug_reset, NULL }, - { "icebear", icebear_jtag_init, icebear_jtag_reset, NULL }, - { "cortino", cortino_jtag_init, comstick_reset, NULL }, - { "signalyzer-h", signalyzer_h_init, signalyzer_h_reset, signalyzer_h_blink }, - { "ktlink", ktlink_init, ktlink_reset, ktlink_blink }, - { NULL, NULL, NULL, NULL }, + { .name = "usbjtag", + .init = usbjtag_init, + .reset = usbjtag_reset, + }, + { .name = "jtagkey", + .init = jtagkey_init, + .reset = jtagkey_reset, + }, + { .name = "jtagkey_prototype_v1", + .init = jtagkey_init, + .reset = jtagkey_reset, + }, + { .name = "oocdlink", + .init = jtagkey_init, + .reset = jtagkey_reset, + }, + { .name = "signalyzer", + .init = usbjtag_init, + .reset = usbjtag_reset, + }, + { .name = "evb_lm3s811", + .init = usbjtag_init, + .reset = usbjtag_reset, + }, + { .name = "luminary_icdi", + .init = usbjtag_init, + .reset = usbjtag_reset, + }, + { .name = "olimex-jtag", + .init = olimex_jtag_init, + .reset = olimex_jtag_reset, + .blink = olimex_jtag_blink + }, + { .name = "flyswatter", + .init = flyswatter_init, + .reset = flyswatter_reset, + .blink = flyswatter_jtag_blink + }, + { .name = "turtelizer2", + .init = turtle_init, + .reset = turtle_reset, + .blink = turtle_jtag_blink + }, + { .name = "comstick", + .init = comstick_init, + .reset = comstick_reset, + }, + { .name = "stm32stick", + .init = stm32stick_init, + .reset = stm32stick_reset, + }, + { .name = "axm0432_jtag", + .init = axm0432_jtag_init, + .reset = axm0432_jtag_reset, + }, + { .name = "sheevaplug", + .init = sheevaplug_init, + .reset = sheevaplug_reset, + }, + { .name = "icebear", + .init = icebear_jtag_init, + .reset = icebear_jtag_reset, + }, + { .name = "cortino", + .init = cortino_jtag_init, + .reset = comstick_reset, + }, + { .name = "signalyzer-h", + .init = signalyzer_h_init, + .reset = signalyzer_h_reset, + .blink = signalyzer_h_blink + }, + { .name = "ktlink", + .init = ktlink_init, + .reset = ktlink_reset, + .blink = ktlink_blink + }, + { .name = NULL, /* END OF TABLE */ }, }; static uint8_t nTRST, nTRSTnOE, nSRST, nSRSTnOE; commit dc342f45f6c8ec02431495863687b3638f1646d5 Author: David Brownell <dbr...@us...> Date: Sun Feb 21 16:55:17 2010 -0800 Developer's Guide: refresh release procedures Be a closer match to what I've actually done for the past few cycles. In particular, hold off pushing repository updates until after the packages are published, as part of opening the merge window, and mention the utility commands which actually create the archives. Signed-off-by: David Brownell <dbr...@us...> diff --git a/doc/manual/release.txt b/doc/manual/release.txt index 70a22ff..056628e 100644 --- a/doc/manual/release.txt +++ b/doc/manual/release.txt @@ -84,8 +84,8 @@ the minor version will @a also be zero (<code>y = 0, z = 0</code>). After these required numeric components, release version strings may contain tags such as as <em>-rc1</em> or <em>-rc2</em>. These 'rc' tags indicate "release candidate" versions of the package. -Like the major/minor/micro numbers, these tags will be manipulated -by the automated release process. +Like major/minor/micro numbers, these are updated +as part of the release process. The release process includes version number manipulations to the tree being released, ensuring that all numbers are incremented (or rolled @@ -277,22 +277,34 @@ support; the Release Manager isn't the only participant. The following steps should be followed to produce each release: --# Produce final patches to mainline (or a release branch). Nobody - except the RM should be committing anything. - -# Finalize @c NEWS file to describe the changes in the release +-# Produce final patches using a local clone of mainline. Nobody + except the RM should be committing anything. <em>Everyone with commit + privileges needs to know and agree to this in advance!</em> Even the RM + only commits a handful of updates as part of the release process + itself ... to files which are part of the version identification scheme + or release process; and to create the version tag; and then to open the + merge window for the next release cycle. + -# Finalize @c the NEWS file to describe the changes in the release - This file is used to automatically post "blurbs" about the project. - - This material should be produced during the development cycle. - - Add a new item for each @c NEWS-worthy contribution, when committed. + - This material should have been produced during the development cycle, + by adding items for each @c NEWS-worthy contribution, when committed + during the merge window. (One part of closing the merge window, by + opening the RC phase of the release, is the commitment to hold all + further such contributions until the next merge window opens.) + - The RM should make sure nothing important was omitted, as part of + the RC1 cycle. From then on, no more updates to NEWS content should + be needed (except to seed the process for the next release, or maybe + if a significant and longstanding bug is fixed late in the RC phase). -# Bump library version if our API changed (not yet required) -# Update and commit the final package version in @c configure.in: - <code>tools/release/version.sh</code> may help ensure the versions - are named consistently: + (The <code>tools/release/version.sh</code> script might help ensure + the versions are named properly.): -# Remove @c -dev tag. - -# Update the @c -rc tag: + -# Update any @c -rc tag: - If producing the final release from an -rc series, remove it - If producing the first RC in a series, add rc1 - If producing the next RC in a series, bump the rc number - -# Commit that version change. + -# Commit that version change, with a good descriptive comment. -# Create a git tag for the final commit, with a tag name matching the version string in <code>configure.in</code> (including <em>-rcN</em> where relevant): @@ -301,49 +313,92 @@ PACKAGE_VERSION="x.y.z" PACKAGE_TAG="v${PACKAGE_VERSION}" git tag -m "The openocd-${PACKAGE_VERSION} release." "${PACKAGE_TAG}" @endverbatim --# Prepare to resume normal development on mainline (major or minor release) - - Update the version label - - Restore @c -dev version tag. - - For a new minor release cycle, increment the release's minor number - - For a new major release cycle, increment the release's major number - and zero its minor number - - Archive @c NEWS file as "<code>doc/news/NEWS-${PACKAGE_VERSION}</code>". - - Create a new @c NEWS file for the next release - - Commit those changes, and push the commit and the release tag - to mainline. --# Produce the package source archives: - -# <em>Start with a new clone of the source tree</em>, with the - release's tag. This is used only for producing these packages. - -# Checkout the appropriate tag: -<code>git checkout "${PACKAGE_VERSION}"</code> - -# @c bootstrap, @c configure, and @c make the package. - -# Run <code>make distcheck</code> to produce the distribution archives. - -# Run <code>make maintainer-clean</code> verify the repository is empty. - -# Create signature files using @c md5sum, @c sha1sum, etc. --# Publish documentation for the release: - - Allow users to access the documentation for each of our releases. - - Place static copies of the following files on the project website: - - @c NEWS: to provide a blurb for each release - - User's Guide, Developer Manual: to allow easy on-line viewing + -# Do not push those changes to mainline yet; only builds using the + source archives you will be creating should ever be labeled as + official releases (with no "-dev" suffix). Since mainline is a + development tree, these will be pushed later, as part of opening + the merge window for the next release cycle (restoring the "-dev" + suffix for that next release.) Those version and tag updates are + the last ones to be included in the release being made. +-# Produce the release files, using the local clone of the source + tree which holds the release's tag and updated version in + @c configure.in ... this is used only to produce the release, and + all files should already be properly checked out. + -# Run <code>tools/release.sh package</code> to produce the + source archives. This automatically bootstraps and + configures the process. + -# Run <code>tools/release.sh stage</code> to create an @c archives + directory with the release data, including MD5 and SHA1 + checksum files (which are used with Berlios). + -# Sanity check at least one of those archives, by extracting and + configuring its contents, using them to build a copy of OpenOCD, + and verifying that the result prints the correct release version + in its startup banner. (For example, + "configure --enable-ft2232_libftdi --enable-parport" + then "make" and run "src/openocd -v" as a sanity check.) + -# Run <code>make docs</code> to create the + documentation which will be published. -# Upload packages and post announcements of their availability: -# Release packages into files section of project sites: - SF.net: - -# Create a new folder named "${PACKAGE_VERSION}" - -# Select new folder as the target for uploads. - -# Upload files via Web interface into new - -# Set platform types for each archive: + -# Under "Project Admin", use the "File Manager" + -# Create a new folder under "openocd" named "${PACKAGE_VERSION}" + -# Upload the @c NEWS file and mark it as the release notes. + -# Upload the three source archive files, using the Web interface, + into that folder. Verify the upload worked OK by checking the + MD5 and SHA1 checksums computed by SourceForge against the + versions created as part of staging the release. + -# Also upload doc/openocd.pdf (the User's Guide) so the version + matching each release will be easily available. + -# Select each file in the release, and use the property panel + to set its type and select the right release notes. - .tar.bz2: Linux, Mac - .tar.gz: BSD, Solaris, Others - .zip: Windows + - For openocd.pdf just associate it with the right release notes. + -# Create an SF.net project news update. - Berlios: - -# Create the new release for the new version. -# Provide @c NEWS file, as requested. - -# Upload files via FTP to ftp://ftp.berlios.de/incoming/ - -# Edit descriptions for each file. + -# Upload the release files via FTP to ftp://ftp.berlios.de/incoming/ + -# Edit descriptions for each file (one at a time) Note that Berlios + does not automatically checksum files, and it uses a very old + version of the SourceForge code with user interface issues. -# Click button to send E-mail Release Notice. + -# Depending on how paranoid you're feeling today, verify the images by + downloading them from the websites and making sure there are no + differences between the downloaded copies and your originals. + -# Publish User's and Developer's Guides to the project web sites: + -# Use SCP to update the SF.net web site with PDF and HTML for the + User's Guide, and HTML for the developer's guide ... you can + instantiate a shell.sourceforge.net instance and set up symlinks + from your home directory, to simplify this process. + -# (How to update the Berlios web site with the same data?) -# Post announcement e-mail to the openocd-development list. - -# Announce updates on freshmeat.net and other trackers. - -# Submit big updates to news feeds (e.g. Digg, Reddit, etc.). + -# optionally: + -# Post an update on the Berlios blog (if it lets you) + -# Announce updates on freshmeat.net and other trackers. + -# Submit updates to news feeds (e.g. Digg, Reddit, etc.). +-# Resume normal development on mainline, by opening the merge window for + the next major or minor release cycle. (You might want to do this + before all the release bits are fully published.) + - Update the version label in the @c configure.in file: + - Restore @c -dev version tag. + - For a new minor release cycle, increment the release's minor number + - For a new major release cycle, increment the release's major number + and zero its minor number + - Archive @c NEWS file as "<code>doc/news/NEWS-${PACKAGE_VERSION}</code>". + - Create a new @c NEWS file for the next release + - Commit those changes. + - Push all the updates to mainline. + - Last updates for the release, including the release tag (you + will need to "git push --tags"). + - Updates opening the merge window + - At this point, it's OK for commiters to start pushing changes + which have been held off until the next release. (Any bugfixes to + this release will be against a bug-fix release branch starting from + the commit you tagged as this release, not mainline.) + - Announce to the openocd-development list. Ideally, you will also + be able to say who is managing the next release cycle. To start a bug-fix release branch: -# Create a new branch, starting from a major or commit c8ea748dc22660dad934537384d35903dfcc492e Author: David Brownell <dbr...@us...> Date: Sun Feb 21 14:58:16 2010 -0800 ADIv5: relocate memacess_tck cycles When using an AP to access a memory (or a memory-mapped register), some extra TCK (assuming JTAG) cycles should be added to ensure the AP has enugh time to complete that access before trying to collect the response. The previous code was adding these cycles *before* trying to access (read or write) data to that address, not *after*. Fix by putting the delays in the right location. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 819dd29..d30dd50 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -119,18 +119,6 @@ static int adi_jtag_dp_scan(struct swjdp_common *swjdp, jtag_set_end_state(TAP_IDLE); arm_jtag_set_instr(jtag_info, instr, NULL); - /* Add specified number of tck clocks before accessing memory bus */ - - /* REVISIT these TCK cycles should be *AFTER* updating APACC, since - * they provide more time for the (MEM) AP to complete the read ... - * See "Minimum Response Time" for JTAG-DP, in the ADIv5 spec. - */ - if ((instr == JTAG_DP_APACC) - && ((reg_addr == AP_REG_DRW) - || ((reg_addr & 0xF0) == AP_REG_BD0)) - && (swjdp->memaccess_tck != 0)) - jtag_add_runtest(swjdp->memaccess_tck, jtag_set_end_state(TAP_IDLE)); - /* Scan out a read or write operation using some DP or AP register. * For APACC access with any sticky error flag set, this is discarded. */ @@ -152,6 +140,18 @@ static int adi_jtag_dp_scan(struct swjdp_common *swjdp, jtag_add_dr_scan(2, fields, jtag_get_end_state()); + /* Add specified number of tck clocks after starting memory bus + * access, giving the hardware time to complete the access. + * They provide more time for the (MEM) AP to complete the read ... + * See "Minimum Response Time" for JTAG-DP, in the ADIv5 spec. + */ + if ((instr == JTAG_DP_APACC) + && ((reg_addr == AP_REG_DRW) + || ((reg_addr & 0xF0) == AP_REG_BD0)) + && (swjdp->memaccess_tck != 0)) + jtag_add_runtest(swjdp->memaccess_tck, + jtag_set_end_state(TAP_IDLE)); + return jtag_get_error(); } commit 3b68a708c2b039d9b091608eccb2206725742a47 Author: David Brownell <dbr...@us...> Date: Sun Feb 21 14:56:56 2010 -0800 ADIv5: remove ATOMIC/COMPOSITE interface mode This removes context-sensitivity from the programming interface and makes it possible to know what a block of code does without needing to know the previous history (specifically, the DAP's "trans_mode" setting). The mode was only set to ATOMIC briefly after DAP initialization, making this patch be primarily cleanup; almost everything depends on COMPOSITE. The transactions which shouldn't have been queued were already properly flushing the queue. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 66b947e..819dd29 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -43,11 +43,16 @@ * is used to access memory mapped resources and is called a MEM-AP. Also a * JTAG-AP is also defined, bridging to JTAG resources; those are uncommon. * - * @todo Remove modality (queued/nonqueued, via DAP trans_mode) from all - * procedure interfaces. Modal programming interfaces are very error prone. - * Procedures should be either queued, or synchronous. Otherwise input - * and output constraints are context-sensitive, and it's hard to know - * what a block of code will do just by reading it. + * This programming interface allows DAP pipelined operations through a + * transaction queue. This primarily affects AP operations (such as using + * a MEM-AP to access memory or registers). If the current transaction has + * not finished by the time the next one must begin, and the ORUNDETECT bit + * is set in the DP_CTRL_STAT register, the SSTICKYORUN status is set and + * further AP operations will fail. There are two basic methods to avoid + * such overrun errors. One involves polling for status instead of using + * transaction piplining. The other involves adding delays to ensure the + * AP has enough time to complete one operation before starting the next + * one. (For JTAG these delays are controlled by memaccess_tck.) */ /* @@ -67,17 +72,6 @@ #include "arm_adi_v5.h" #include <helper/time_support.h> -/* - * Transaction Mode: - * swjdp->trans_mode = TRANS_MODE_COMPOSITE; - * Uses Overrun checking mode and does not do actual JTAG send/receive or transaction - * result checking until swjdp_end_transaction() - * This must be done before using or deallocating any return variables. - * swjdp->trans_mode == TRANS_MODE_ATOMIC - * All reads and writes to the AHB bus are checked for valid completion, and return values - * are immediatley available. -*/ - /* ARM ADI Specification requires at least 10 bits used for TAR autoincrement */ @@ -191,47 +185,32 @@ static int adi_jtag_dp_scan_u32(struct swjdp_common *swjdp, /** * Utility to write AP registers. */ -static int ap_write_check(struct swjdp_common *dap, +static inline int ap_write_check(struct swjdp_common *dap, uint8_t reg_addr, uint8_t *outvalue) { - adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg_addr, DPAP_WRITE, + return adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg_addr, DPAP_WRITE, outvalue, NULL, NULL); - - /* REVISIT except in dap_setup_accessport() almost all call paths - * set up COMPOSITE. Probably worth just inlining the scan... - */ - - /* In TRANS_MODE_ATOMIC all JTAG_DP_APACC transactions wait for - * ack = OK/FAULT and the check CTRL_STAT - */ - if (dap->trans_mode == TRANS_MODE_ATOMIC) - return jtagdp_transaction_endcheck(dap); - - return ERROR_OK; } static int scan_inout_check_u32(struct swjdp_common *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint32_t outvalue, uint32_t *invalue) { + int retval; + /* Issue the read or write */ - adi_jtag_dp_scan_u32(swjdp, instr, reg_addr, RnW, outvalue, NULL, NULL); + retval = adi_jtag_dp_scan_u32(swjdp, instr, reg_addr, + RnW, outvalue, NULL, NULL); + if (retval != ERROR_OK) + return retval; /* For reads, collect posted value; RDBUFF has no other effect. * Assumes read gets acked with OK/FAULT, and CTRL_STAT says "OK". */ if ((RnW == DPAP_READ) && (invalue != NULL)) - adi_jtag_dp_scan_u32(swjdp, JTAG_DP_DPACC, + retval = adi_jtag_dp_scan_u32(swjdp, JTAG_DP_DPACC, DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack); - - /* In TRANS_MODE_ATOMIC all JTAG_DP_APACC transactions wait for - * ack = OK/FAULT and then check CTRL_STAT - */ - if ((instr == JTAG_DP_APACC) - && (swjdp->trans_mode == TRANS_MODE_ATOMIC)) - return jtagdp_transaction_endcheck(swjdp); - - return ERROR_OK; + return retval; } int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) @@ -437,17 +416,13 @@ static int dap_ap_write_reg(struct swjdp_common *swjdp, } /** - * Write an AP register value. - * This is synchronous iff the mode is set to ATOMIC, in which - * case any queued transactions are flushed. + * Asynchronous (queued) AP register write. * * @param swjdp The DAP whose currently selected AP will be written. * @param reg_addr Eight bit AP register address. * @param value Word to be written at reg_addr * - * @return In synchronous mode: ERROR_OK for success, and the register holds - * the specified value; else a fault code. In asynchronous mode, a status - * code reflecting whether the transaction was properly queued. + * @return ERROR_OK if the transaction was properly queued, else a fault code. */ int dap_ap_write_reg_u32(struct swjdp_common *swjdp, uint32_t reg_addr, uint32_t value) @@ -460,17 +435,13 @@ int dap_ap_write_reg_u32(struct swjdp_common *swjdp, } /** - * Read an AP register value. - * This is synchronous iff the mode is set to ATOMIC, in which - * case any queued transactions are flushed. + * Asynchronous (queued) AP register eread. * * @param swjdp The DAP whose currently selected AP will be read. * @param reg_addr Eight bit AP register address. * @param value Points to where the 32-bit (little-endian) word will be stored. * - * @return In synchronous mode: ERROR_OK for success, and *value holds - * the specified value; else a fault code. In asynchronous mode, a status - * code reflecting whether the transaction was properly queued. + * @return ERROR_OK if the transaction was properly queued, else a fault code. */ int dap_ap_read_reg_u32(struct swjdp_common *swjdp, uint32_t reg_addr, uint32_t *value) @@ -486,9 +457,8 @@ int dap_ap_read_reg_u32(struct swjdp_common *swjdp, } /** - * Set up transfer parameters for the currently selected MEM-AP. - * This is synchronous iff the mode is set to ATOMIC, in which - * case any queued transactions are flushed. + * Queue transactions setting up transfer parameters for the + * currently selected MEM-AP. * * Subsequent transfers using registers like AP_REG_DRW or AP_REG_BD2 * initiate data reads or writes using memory or peripheral addresses. @@ -503,9 +473,7 @@ int dap_ap_read_reg_u32(struct swjdp_common *swjdp, * @param tar MEM-AP Transfer Address Register (TAR) to assign. If this * matches the cached address, the register is not changed. * - * @return In synchronous mode: ERROR_OK for success, and the AP is set - * up as requested else a fault code. In asynchronous mode, a status - * code reflecting whether the transaction was properly queued. + * @return ERROR_OK if the transaction was properly queued, else a fault code. */ int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar) { @@ -550,8 +518,6 @@ int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, { int retval; - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - /* Use banked addressing (REG_BDx) to avoid some link traffic * (updating TAR) when reading several consecutive addresses. */ @@ -603,8 +569,6 @@ int mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, { int retval; - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - /* Use banked addressing (REG_BDx) to avoid some link traffic * (updating TAR) when writing several consecutive addresses. */ @@ -652,8 +616,6 @@ int mem_ap_write_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t adr = address; uint8_t* pBuffer = buffer; - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - count >>= 2; wcount = count; @@ -721,8 +683,6 @@ static int mem_ap_write_buf_packed_u16(struct swjdp_common *swjdp, int retval = ERROR_OK; int wcount, blocksize, writecount, i; - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - wcount = count >> 1; while (wcount > 0) @@ -799,8 +759,6 @@ int mem_ap_write_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, if (count >= 4) return mem_ap_write_buf_packed_u16(swjdp, buffer, count, address); - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - while (count > 0) { dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address); @@ -823,8 +781,6 @@ static int mem_ap_write_buf_packed_u8(struct swjdp_common *swjdp, int retval = ERROR_OK; int wcount, blocksize, writecount, i; - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - wcount = count; while (wcount > 0) @@ -896,8 +852,6 @@ int mem_ap_write_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, if (count >= 4) return mem_ap_write_buf_packed_u8(swjdp, buffer, count, address); - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - while (count > 0) { dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address); @@ -925,8 +879,6 @@ int mem_ap_read_buf_u32(struct swjdp_common *swjdp, uint8_t *buffer, int count, uint32_t adr = address; uint8_t* pBuffer = buffer; - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - count >>= 2; wcount = count; @@ -1009,8 +961,6 @@ static int mem_ap_read_buf_packed_u16(struct swjdp_common *swjdp, int retval = ERROR_OK; int wcount, blocksize, readcount, i; - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - wcount = count >> 1; while (wcount > 0) @@ -1063,8 +1013,6 @@ int mem_ap_read_buf_u16(struct swjdp_common *swjdp, uint8_t *buffer, int count, if (count >= 4) return mem_ap_read_buf_packed_u16(swjdp, buffer, count, address); - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - while (count > 0) { dap_setup_accessport(swjdp, CSW_16BIT | CSW_ADDRINC_SINGLE, address); @@ -1105,8 +1053,6 @@ static int mem_ap_read_buf_packed_u8(struct swjdp_common *swjdp, int retval = ERROR_OK; int wcount, blocksize, readcount, i; - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - wcount = count; while (wcount > 0) @@ -1156,8 +1102,6 @@ int mem_ap_read_buf_u8(struct swjdp_common *swjdp, uint8_t *buffer, int count, u if (count >= 4) return mem_ap_read_buf_packed_u8(swjdp, buffer, count, address); - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - while (count > 0) { dap_setup_accessport(swjdp, CSW_8BIT | CSW_ADDRINC_SINGLE, address); @@ -1203,7 +1147,6 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) dap_ap_select(swjdp, 0); /* DP initialization */ - swjdp->trans_mode = TRANS_MODE_ATOMIC; dap_dp_read_reg(swjdp, &dummy, DP_CTRL_STAT); dap_dp_write_reg(swjdp, SSTICKYERR, DP_CTRL_STAT); dap_dp_read_reg(swjdp, &dummy, DP_CTRL_STAT); diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 746f1cb..316701e 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -118,13 +118,6 @@ #define CSW_MASTER_DEBUG (1 << 29) /* ? */ #define CSW_DBGSWENABLE (1 << 31) -/* transaction mode */ -#define TRANS_MODE_NONE 0 -/* Transaction waits for previous to complete */ -#define TRANS_MODE_ATOMIC 1 -/* Freerunning transactions with delays and overrun checking */ -#define TRANS_MODE_COMPOSITE 2 - /** * This represents an ARM Debug Interface (v5) Debug Access Port (DAP). * A DAP has two types of component: one Debug Port (DP), which is a @@ -170,9 +163,8 @@ struct swjdp_common uint32_t ap_tar_value; /* information about current pending SWjDP-AHBAP transaction */ - uint8_t trans_mode; - uint8_t trans_rw; uint8_t ack; + /** * Configures how many extra tck clocks are added after starting a * MEM-AP access before we try to read its status (and/or result). @@ -192,7 +184,7 @@ static inline uint8_t dap_ap_get_select(struct swjdp_common *swjdp) /* AP selection applies to future AP transactions */ void dap_ap_select(struct swjdp_common *dap,uint8_t apsel); -/* AP transactions ... synchronous given TRANS_MODE_ATOMIC */ +/* Queued AP transactions */ int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar); int dap_ap_write_reg_u32(struct swjdp_common *swjdp, diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 3dd9468..3ebc34a 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -70,8 +70,6 @@ static int cortexm3_dap_read_coreregister_u32(struct swjdp_common *swjdp, mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr); - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */ dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0); dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum); @@ -101,8 +99,6 @@ static int cortexm3_dap_write_coreregister_u32(struct swjdp_common *swjdp, mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr); - swjdp->trans_mode = TRANS_MODE_COMPOSITE; - /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */ dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0); dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value); commit ecff73043c1ddcc97d4d1ea1c87f251a850b22d4 Author: David Brownell <dbr...@us...> Date: Sun Feb 21 14:54:54 2010 -0800 ARM: ADIv5, deadcode cleanup I have no idea what the scan_inout_check() was *expecting* to achieve by issuing a read of the DP_RDBUFF register. But in any case, that code was clearly never being called ("invalue" always NULL) ... so remove it, and the associated comment. Also rename it as ap_write_check(), facilitating a cleanup of its single call site by removing constant parameters. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index d7afb58..66b947e 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -188,23 +188,24 @@ static int adi_jtag_dp_scan_u32(struct swjdp_common *swjdp, return retval; } -/* scan_inout_check adds one extra inscan for DPAP_READ commands to read variables */ -static int scan_inout_check(struct swjdp_common *swjdp, - uint8_t instr, uint8_t reg_addr, uint8_t RnW, - uint8_t *outvalue, uint8_t *invalue) +/** + * Utility to write AP registers. + */ +static int ap_write_check(struct swjdp_common *dap, + uint8_t reg_addr, uint8_t *outvalue) { - adi_jtag_dp_scan(swjdp, instr, reg_addr, RnW, outvalue, NULL, NULL); + adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg_addr, DPAP_WRITE, + outvalue, NULL, NULL); - if ((RnW == DPAP_READ) && (invalue != NULL)) - adi_jtag_dp_scan(swjdp, JTAG_DP_DPACC, - DP_RDBUFF, DPAP_READ, 0, invalue, &swjdp->ack); + /* REVISIT except in dap_setup_accessport() almost all call paths + * set up COMPOSITE. Probably worth just inlining the scan... + */ /* In TRANS_MODE_ATOMIC all JTAG_DP_APACC transactions wait for * ack = OK/FAULT and the check CTRL_STAT */ - if ((instr == JTAG_DP_APACC) - && (swjdp->trans_mode == TRANS_MODE_ATOMIC)) - return jtagdp_transaction_endcheck(swjdp); + if (dap->trans_mode == TRANS_MODE_ATOMIC) + return jtagdp_transaction_endcheck(dap); return ERROR_OK; } @@ -432,8 +433,7 @@ static int dap_ap_write_reg(struct swjdp_common *swjdp, if (retval != ERROR_OK) return retval; - return scan_inout_check(swjdp, JTAG_DP_APACC, reg_addr, - DPAP_WRITE, out_value_buf, NULL); + return ap_write_check(swjdp, reg_addr, out_value_buf); } /** commit 39cfe6279616a69b858ddd3493d61ed7133ff081 Author: David Brownell <dbr...@us...> Date: Sun Feb 21 14:53:15 2010 -0800 ARM: ADIv5 code shrinkage, cleanup adi_jtag_dp_scan_u32() now wraps adi_jtag_dp_scan(), removing code duplication. Include doxygen for the former. Comment some particularly relevant points. Minor fault handling fixes for both routines: don't register a callback that can't run, or return ERROR_OK after an error. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 1eff335..d7afb58 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -158,58 +158,34 @@ static int adi_jtag_dp_scan(struct swjdp_common *swjdp, jtag_add_dr_scan(2, fields, jtag_get_end_state()); - return ERROR_OK; + return jtag_get_error(); } -/* Scan out and in from host ordered uint32_t variables */ +/** + * Scan DPACC or APACC out and in from host ordered uint32_t buffers. + * This is exactly like adi_jtag_dp_scan(), except that endianness + * conversions are performed (so the types of invalue and outvalue + * must be different). + */ static int adi_jtag_dp_scan_u32(struct swjdp_common *swjdp, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint32_t outvalue, uint32_t *invalue, uint8_t *ack) { - struct arm_jtag *jtag_info = swjdp->jtag_info; - struct scan_field fields[2]; uint8_t out_value_buf[4]; - uint8_t out_addr_buf; - - jtag_set_end_state(TAP_IDLE); - arm_jtag_set_instr(jtag_info, instr, NULL); - - /* Add specified number of tck clocks before accessing memory bus */ - - /* REVISIT these TCK cycles should be *AFTER* updating APACC, since - * they provide more time for the (MEM) AP to complete the read ... - */ - if ((instr == JTAG_DP_APACC) - && ((reg_addr == AP_REG_DRW) - || ((reg_addr & 0xF0) == AP_REG_BD0)) - && (swjdp->memaccess_tck != 0)) - jtag_add_runtest(swjdp->memaccess_tck, jtag_set_end_state(TAP_IDLE)); - - fields[0].tap = jtag_info->tap; - fields[0].num_bits = 3; - buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1)); - fields[0].out_value = &out_addr_buf; - fields[0].in_value = ack; + int retval; - fields[1].tap = jtag_info->tap; - fields[1].num_bits = 32; buf_set_u32(out_value_buf, 0, 32, outvalue); - fields[1].out_value = out_value_buf; - fields[1].in_value = NULL; - - if (invalue) - { - fields[1].in_value = (uint8_t *)invalue; - jtag_add_dr_scan(2, fields, jtag_get_end_state()); - jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t) invalue); - } else - { + retval = adi_jtag_dp_scan(swjdp, instr, reg_addr, RnW, + out_value_buf, (uint8_t *)invalue, ack); + if (retval != ERROR_OK) + return retval; - jtag_add_dr_scan(2, fields, jtag_get_end_state()); - } + if (invalue) + jtag_add_callback(arm_le_to_h_u32, + (jtag_callback_data_t) invalue); - return ERROR_OK; + return retval; } /* scan_inout_check adds one extra inscan for DPAP_READ commands to read variables */ commit a97bb67543eacde38f093610982812f714e7a050 Author: David Brownell <dbr...@us...> Date: Sun Feb 21 14:51:19 2010 -0800 ADIv5 clean up AP fault handling Pass up fault codes from various routines, so their callers can clean up after failures, and remove the FIXME comments highlighting those previously goofy code paths. dap_ap_{read,write}_reg_u32() dap_ap_write_reg() mem_ap_{read,write}_u32() mem_ap_{read,write}_atomic_u32() dap_setup_accessport() Make dap_ap_write_reg_u32() just wrap dap_ap_write_reg(), instead of cloning its core code (and broken fault handling). Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 2e3dafb..1eff335 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -450,12 +450,14 @@ static int dap_ap_bankselect(struct swjdp_common *swjdp, uint32_t ap_reg) static int dap_ap_write_reg(struct swjdp_common *swjdp, uint32_t reg_addr, uint8_t *out_value_buf) { - dap_ap_bankselect(swjdp, reg_addr); - scan_inout_check(swjdp, JTAG_DP_APACC, reg_addr, - DPAP_WRITE, out_value_buf, NULL); + int retval; - /* FIXME return fault code from above calls */ - return ERROR_OK; + retval = dap_ap_bankselect(swjdp, reg_addr); + if (retval != ERROR_OK) + return retval; + + return scan_inout_check(swjdp, JTAG_DP_APACC, reg_addr, + DPAP_WRITE, out_value_buf, NULL); } /** @@ -477,12 +479,8 @@ int dap_ap_write_reg_u32(struct swjdp_common *swjdp, uint8_t out_value_buf[4]; buf_set_u32(out_value_buf, 0, 32, value); - dap_ap_bankselect(swjdp, reg_addr); - scan_inout_check(swjdp, JTAG_DP_APACC, reg_addr, - DPAP_WRITE, out_value_buf, NULL); - - /* FIXME return any fault code from above calls */ - return ERROR_OK; + return dap_ap_write_reg(swjdp, + reg_addr, out_value_buf); } /** @@ -501,12 +499,14 @@ int dap_ap_write_reg_u32(struct swjdp_common *swjdp, int dap_ap_read_reg_u32(struct swjdp_common *swjdp, uint32_t reg_addr, uint32_t *value) { - dap_ap_bankselect(swjdp, reg_addr); - scan_inout_check_u32(swjdp, JTAG_DP_APACC, reg_addr, - DPAP_READ, 0, value); + int retval; - /* FIXME return any fault code from above calls */ - return ERROR_OK; + retval = dap_ap_bankselect(swjdp, reg_addr); + if (retval != ERROR_OK) + return retval; + + return scan_inout_check_u32(swjdp, JTAG_DP_APACC, reg_addr, + DPAP_READ, 0, value); } /** @@ -533,19 +533,23 @@ int dap_ap_read_reg_u32(struct swjdp_common *swjdp, */ int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar) { + int retval; + csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT; if (csw != swjdp->ap_csw_value) { /* LOG_DEBUG("DAP: Set CSW %x",csw); */ - /* FIXME if this call fails, fail this procedure! */ - dap_ap_write_reg_u32(swjdp, AP_REG_CSW, csw); + retval = dap_ap_write_reg_u32(swjdp, AP_REG_CSW, csw); + if (retval != ERROR_OK) + return retval; swjdp->ap_csw_value = csw; } if (tar != swjdp->ap_tar_value) { /* LOG_DEBUG("DAP: Set TAR %x",tar); */ - /* FIXME if this call fails, fail this procedure! */ - dap_ap_write_reg_u32(swjdp, AP_REG_TAR, tar); + retval = dap_ap_write_reg_u32(swjdp, AP_REG_TAR, tar); + if (retval != ERROR_OK) + return retval; swjdp->ap_tar_value = tar; } /* Disable TAR cache when autoincrementing */ @@ -568,17 +572,19 @@ int dap_setup_accessport(struct swjdp_common *swjdp, uint32_t csw, uint32_t tar) int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t *value) { + int retval; + swjdp->trans_mode = TRANS_MODE_COMPOSITE; /* Use banked addressing (REG_BDx) to avoid some link traffic * (updating TAR) when reading several consecutive addresses. */ - dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, + retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, address & 0xFFFFFFF0); - dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), value); + if (retval != ERROR_OK) + return retval; - /* FIXME return any fault code from above calls */ - return ERROR_OK; + return dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), value); } /** @@ -596,8 +602,11 @@ int mem_ap_read_u32(struct swjdp_common *swjdp, uint32_t address, int mem_ap_read_atomic_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t *value) { - mem_ap_read_u32(swjdp, address, value); - /* FIXME return any fault code from above call */ + int retval; + + retval = mem_ap_read_u32(swjdp, address, value); + if (retval != ERROR_OK) + return retval; return jtagdp_transaction_endcheck(swjdp); } @@ -616,17 +625,20 @@ int mem_ap_read_atomic_u32(struct swjdp_common *swjdp, uint32_t address, int mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t value) { + int retval; + swjdp->trans_mode = TRANS_MODE_COMPOSITE; /* Use banked addressing (REG_BDx) to avoid some link traffic * (updating TAR) when writing several consecutive addresses. */ - dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, + retval = dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, address & 0xFFFFFFF0); - dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), value); + if (retval != ERROR_OK) + return retval; - /* FIXME return any fault code from above calls */ - return ERROR_OK; + return dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (address & 0xC), + value); } /** @@ -643,8 +655,10 @@ int mem_ap_write_u32(struct swjdp_common *swjdp, uint32_t address, int mem_ap_write_atomic_u32(struct swjdp_common *swjdp, uint32_t address, uint32_t value) { - mem_ap_write_u32(swjdp, address, value); - /* FIXME return any fault code from above call */ + int retval = mem_ap_write_u32(swjdp, address, value); + + if (retval != ERROR_OK) + return retval; return jtagdp_transaction_endcheck(swjdp); } commit 249263d29da11b0ec981c2e0d520cd7dcf08939b Author: David Brownell <dbr...@us...> Date: Sun Feb 21 14:48:04 2010 -0800 ADIv5 clean up AP selection and register caching Handling of AP (and AP register bank) selection, and cached AP registers, is pretty loose ... start tightening it: - It's "AP bank" select support ... there are no DP banks. Rename. + dap_dp_bankselect() becomes dap_ap_bankselect() + "dp_select_value" struct field becomes "ap_bank_value" - Remove duplicate AP cache init paths ... only use dap_ap_select(), and don't make Cortex (A8 or M3) cores roll their own code. - For dap_ap_bankselect(), pass up any fault code from writing the SELECT register. (Nothing yet checks those codes.) - Add various bits of Doxygen Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 94c8ed8..2e3dafb 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -349,7 +349,7 @@ int jtagdp_transaction_endcheck(struct swjdp_common *swjdp) "ap_bank 0x%" PRIx32 ", ap_csw 0x%" PRIx32 ", ap_tar 0x%" PRIx32, - swjdp->dp_select_value, + swjdp->ap_bank_value, swjdp->ap_csw_value, swjdp->ap_tar_value); @@ -419,38 +419,38 @@ static int dap_dp_read_reg(struct swjdp_common *swjdp, */ void dap_ap_select(struct swjdp_common *swjdp,uint8_t apsel) { - uint32_t select; - select = (apsel << 24) & 0xFF000000; + uint32_t select = (apsel << 24) & 0xFF000000; if (select != swjdp->apsel) { swjdp->apsel = select; - /* Switching AP invalidates cached values */ - swjdp->dp_select_value = -1; + /* Switching AP invalidates cached values. + * Values MUST BE UPDATED BEFORE AP ACCESS. + */ + swjdp->ap_bank_value = -1; swjdp->ap_csw_value = -1; swjdp->ap_tar_value = -1; } } -static int dap_dp_bankselect(struct swjdp_common *swjdp, uint32_t ap_reg) +/** Select the AP register bank matching bits 7:4 of ap_reg. */ +static int dap_ap_bankselect(struct swjdp_common *swjdp, uint32_t ap_reg) { - uint32_t select; - select = (ap_reg & 0x000000F0); + uint32_t select = (ap_reg & 0x000000F0); - if (select != swjdp->dp_select_value) + if (select != swjdp->ap_bank_value) { - dap_dp_write_reg(swjdp, select | swjdp->apsel, DP_SELECT); - swjdp->dp_select_value = select; - } - - /* FIXME return any fault code from write() call */ - return ERROR_OK; + swjdp->ap_bank_value = select; + select |= swjdp->apsel; + return dap_dp_write_reg(swjdp, select, DP_SELECT); + } else + return ERROR_OK; } static int dap_ap_write_reg(struct swjdp_common *swjdp, uint32_t reg_addr, uint8_t *out_value_buf) { - dap_dp_bankselect(swjdp, reg_addr); + dap_ap_bankselect(swjdp, reg_addr); scan_inout_check(swjdp, JTAG_DP_APACC, reg_addr, DPAP_WRITE, out_value_buf, NULL); @@ -477,7 +477,7 @@ int dap_ap_write_reg_u32(struct swjdp_common *swjdp, uint8_t out_value_buf[4]; buf_set_u32(out_value_buf, 0, 32, value); - dap_dp_bankselect(swjdp, reg_addr); + dap_ap_bankselect(swjdp, reg_addr); scan_inout_check(swjdp, JTAG_DP_APACC, reg_addr, DPAP_WRITE, out_value_buf, NULL); @@ -501,7 +501,7 @@ int dap_ap_write_reg_u32(struct swjdp_common *swjdp, int dap_ap_read_reg_u32(struct swjdp_common *swjdp, uint32_t reg_addr, uint32_t *value) { - dap_dp_bankselect(swjdp, reg_addr); + dap_ap_bankselect(swjdp, reg_addr); scan_inout_check_u32(swjdp, JTAG_DP_APACC, reg_addr, DPAP_READ, 0, value); @@ -1206,12 +1206,11 @@ int ahbap_debugport_init(struct swjdp_common *swjdp) /* Default MEM-AP setup. * * REVISIT AP #0 may be an inappropriate default for this. - * Should we probe, or receve a hint from the caller? + * Should we probe, or take a hint from the caller? * Presumably we can ignore the possibility of multiple APs. */ - swjdp->apsel = 0; - swjdp->ap_csw_value = -1; - swjdp->ap_tar_value = -1; + swjdp->apsel = !0; + dap_ap_select(swjdp, 0); /* DP initialization */ swjdp->trans_mode = TRANS_MODE_ATOMIC; diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 759f233..746f1cb 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -138,17 +138,45 @@ struct swjdp_common struct arm_jtag *jtag_info; /* Control config */ uint32_t dp_ctrl_stat; - /* Support for several AP's in one DAP */ + + /** + * Cache for DP_SELECT bits identifying the current AP. A DAP may + * connect to multiple APs, such as one MEM-AP for general access, + * another reserved for accessing debug modules, and a JTAG-DP. + * "-1" indicates no cached value. + */ uint32_t apsel; - /* Register select cache */ - uint32_t dp_select_value; + + /** + * Cache for DP_SELECT bits identifying the current four-word AP + * register bank. This caches AP register addresss bits 7:4; JTAG + * and SWD access primitves pass address bits 3:2; bits 1:0 are zero. + * "-1" indicates no cached value. + */ + uint32_t ap_bank_value; + + /** + * Cache for (MEM-AP) AP_REG_CSW register value. This is written to + * configure an access mode, such as autoincrementing AP_REG_TAR during + * word access. "-1" indicates no cached value. + */ uint32_t ap_csw_value; + + /** + * Cache for (MEM-AP) AP_REG_TAR register value This is written to + * configure the address being read or written + * "-1" indicates no cached value. + */ uint32_t ap_tar_value; + /* information about current pending SWjDP-AHBAP transaction */ uint8_t trans_mode; uint8_t trans_rw; uint8_t ack; - /* extra tck clocks for memory bus access */ + /** + * Configures how many extra tck clocks are added after starting a + * MEM-AP access before we try to read its status (and/or result). + */ uint32_t memaccess_tck; /* Size of TAR autoincrement block, ARM ADI Specification requires at least 10 bits */ uint32_t tar_autoincr_block; diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c index 050238c..f4818f8 100644 --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -53,7 +53,9 @@ static int cortex_a8_dap_write_coreregister_u32(struct target *target, uint32_t value, int regnum); /* * FIXME do topology discovery using the ROM; don't - * assume this is an OMAP3. + * assume this is an OMAP3. Also, allow for multiple ARMv7-A + * cores, with different AP numbering ... don't use a #define + * for these numbers, use per-core armv7a state. */ #define swjdp_memoryap 0 #define swjdp_debugap 1 @@ -1570,9 +1572,7 @@ static int cortex_a8_init_arch_info(struct target *target, cortex_a8->jtag_info.tap = tap; cortex_a8->jtag_info.scann_size = 4; - swjdp->dp_select_value = -1; - swjdp->ap_csw_value = -1; - swjdp->ap_tar_value = -1; + /* Leave (only) generic DAP stuff for debugport_init() */ swjdp->jtag_info = &cortex_a8->jtag_info; swjdp->memaccess_tck = 80; diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index a3b3d42..3dd9468 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -1848,12 +1848,11 @@ static int cortex_m3_init_arch_info(struct target *target, cortex_m3->jtag_info.tap = tap; cortex_m3->jtag_info.scann_size = 4; - armv7m->swjdp_info.dp_select_value = -1; - armv7m->swjdp_info.ap_csw_value = -1; - armv7m->swjdp_info.ap_tar_value = -1; + /* Leave (only) generic DAP stuff for debugport_init(); */ armv7m->swjdp_info.jtag_info = &cortex_m3->jtag_info; armv7m->swjdp_info.memaccess_tck = 8; - armv7m->swjdp_info.tar_autoincr_block = (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */ + /* Cortex-M3 has 4096 bytes autoincrement range */ + armv7m->swjdp_info.tar_autoincr_block = (1 << 12); /* register arch-specific functions */ armv7m->examine_debug_reason = cortex_m3_examine_debug_reason; commit 1aac72d24339380f6e98c50dec4c96ab30537749 Author: David Brownell <dbr...@us...> Date: Sun Feb 21 14:34:33 2010 -0800 ARM: keep a handle to the PC Keep a handle to the PC in "struct arm", and use it. This register is used a fair amount, so this is a net minor code shrink (other than some line length fixes), but mostly it's to make things more readable. For XScale, fix a dodgy sequence while stepping. It was initializing a variable to a non-NULL value, then updating it to handle the step-over-active-breakpoint case, and then later testing for non-NULL to see if it should reverse that step-over-active logic. It should have done like ARM7/ARM9 does: init to NULL. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm.h b/src/target/arm.h index c72b194..6b304e9 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -95,6 +95,9 @@ struct arm { int common_magic; struct reg_cache *core_cache; + /** Handle to the PC; valid in all core modes. */ + struct reg *pc; + /** Handle to the CPSR; valid in all core modes. */ struct reg *cpsr; diff --git a/src/target/arm11.c b/src/target/arm11.c index 678d8ac..51be701 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -451,7 +451,7 @@ static int arm11_halt(struct target *target) static uint32_t arm11_nextpc(struct arm11_common *arm11, int current, uint32_t address) { - void *value = arm11->arm.core_cache->reg_list[15].value; + void *value = arm11->arm.pc->value; if (!current) buf_set_u32(value, 0, 32, address); diff --git a/src/target/arm720t.c b/src/target/arm720t.c index efafa5e..2275935 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -361,9 +361,9 @@ static int arm720t_soft_reset_halt(struct target *target) armv4_5->cpsr->dirty = 1; /* start fetching from 0x0 */ - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0); - armv4_5->core_cache->reg_list[15].dirty = 1; - armv4_5->core_cache->reg_list[15].valid = 1; + buf_set_u32(armv4_5->pc->value, 0, 32, 0x0); + armv4_5->pc->dirty = 1; + armv4_5->pc->valid = 1; arm720t_disable_mmu_caches(target, 1, 1, 1); arm720t->armv4_5_mmu.mmu_enabled = 0; diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 509e91e..2176729 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -1235,9 +1235,9 @@ int arm7_9_soft_reset_halt(struct target *target) armv4_5->cpsr->dirty = 1; /* start fetching from 0x0 */ - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0); - armv4_5->core_cache->reg_list[15].dirty = 1; - armv4_5->core_cache->reg_list[15].valid = 1; + buf_set_u32(armv4_5->pc->value, 0, 32, 0x0); + armv4_5->pc->dirty = 1; + armv4_5->pc->valid = 1; /* reset registers */ for (i = 0; i <= 14; i++) @@ -1721,9 +1721,10 @@ int arm7_9_restore_context(struct target *target) } /* restore PC */ - LOG_DEBUG("writing PC with value 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); - arm7_9->write_pc(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); - armv4_5->core_cache->reg_list[15].dirty = 0; + LOG_DEBUG("writing PC with value 0x%8.8" PRIx32, + buf_get_u32(armv4_5->pc->value, 0, 32)); + arm7_9->write_pc(target, buf_get_u32(armv4_5->pc->value, 0, 32)); + armv4_5->pc->dirty = 0; if (arm7_9->post_restore_context) arm7_9->post_restore_context(target); @@ -1815,15 +1816,17 @@ int arm7_9_resume(struct target *target, int current, uint32_t address, int hand /* current = 1: continue on current pc, otherwise continue at <address> */ if (!current) - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address); + buf_set_u32(armv4_5->pc->value, 0, 32, address); uint32_t current_pc; - current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + current_pc = buf_get_u32(armv4_5->pc->value, 0, 32); /* the front-end may request us not to handle breakpoints */ if (handle_breakpoints) { - if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)))) + breakpoint = breakpoint_find(target, + buf_get_u32(armv4_5->pc->value, 0, 32)); + if (breakpoint != NULL) { LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (id: %d)", breakpoint->address, breakpoint->unique_id ); if ((retval = arm7_9_unset_breakpoint(target, breakpoint)) != ERROR_OK) @@ -1881,7 +1884,8 @@ int arm7_9_resume(struct target *target, int current, uint32_t address, int hand } arm7_9_debug_entry(target); - LOG_DEBUG("new PC after step: 0x%8.8" PRIx32 "", buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)); + LOG_DEBUG("new PC after step: 0x%8.8" PRIx32, + buf_get_u32(armv4_5->pc->value, 0, 32)); LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address); if ((retval = arm7_9_set_breakpoint(target, breakpoint)) != ERROR_OK) @@ -1957,7 +1961,7 @@ void arm7_9_enable_eice_step(struct target *target, uint32_t next_pc) struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm *armv4_5 = &arm7_9->armv4_5_common; uint32_t current_pc; - current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + current_pc = buf_get_u32(armv4_5->pc->value, 0, 32); if (next_pc != current_pc) { @@ -2019,18 +2023,18 @@ int arm7_9_step(struct target *target, int current, uint32_t address, int handle /* current = 1: continue on current pc, otherwise continue at <address> */ if (!current) - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, address); + buf_set_u32(armv4_5->pc->value, 0, 32, address); - uint32_t current_pc; - current_pc = buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32); + uint32_t current_pc = buf_get_u32(armv4_5->pc->value, 0, 32); /* the front-end may request us not to handle breakpoints */ if (handle_breakpoints) - if ((breakpoint = breakpoint_find(target, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32)))) - if ((retval = arm7_9_unset_breakpoint(target, breakpoint)) != ERROR_OK) - { - return retval; - } + breakpoint = breakpoint_find(target, current_pc); + if (breakpoint != NULL) { + retval = arm7_9_unset_breakpoint(target, breakpoint); + if (retval != ERROR_OK) + return retval; + } target->debug_reason = DBG_REASON_SINGLESTEP; diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index 16f16b0..530a675 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -598,7 +598,8 @@ static void arm7tdmi_branch_resume_thumb(struct target *target) /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */ - arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0); + arm7tdmi_clock_out(jtag_info, + buf_get_u32(armv4_5->pc->value, 0, 32) | 1, NULL, 0); /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */ arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); diff --git a/src/target/arm920t.c b/src/target/arm920t.c index 3e61545..152edcf 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -777,9 +777,9 @@ int arm920t_soft_reset_halt(struct target *target) armv4_5->cpsr->dirty = 1; /* start fetching from 0x0 */ - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0); - armv4_5->core_cache->reg_list[15].dirty = 1; - armv4_5->core_cache->reg_list[15].valid = 1; + buf_set_u32(armv4_5->pc->value, 0, 32, 0x0); + armv4_5->pc->dirty = 1; + armv4_5->pc->valid = 1; arm920t_disable_mmu_caches(target, 1, 1, 1); arm920t->armv4_5_mmu.mmu_enabled = 0; diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index 32ecf72..d811196 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -569,9 +569,9 @@ int arm926ejs_soft_reset_halt(struct target *target) armv4_5->cpsr->dirty = 1; /* start fetching from 0x0 */ - buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0); - armv4_5->core_cache->reg_list[15].dirty = 1; - armv4_5->core_cache->reg_list[15].valid = 1; + buf_set_u32(armv4_5->pc->value, 0, 32, 0x0); + armv4_5->pc->dirty = 1; + armv4_5->pc->valid = 1; arm926ejs_disable_mmu_caches(target, 1, 1, 1); arm926ejs->armv4_5_mmu.mmu_enabled = 0; diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index 761e7cf..77b01b1 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -677,7 +677,8 @@ static void arm9tdmi_branch_resume_thumb(struct target *target) /* fetch NOP, LDM in EXECUTE stage (1st cycle) */ arm9tdmi_clock_out(jtag_info, ARMV4_5... [truncated message content] |
From: David B. <dbr...@us...> - 2010-02-21 23:20:19
|
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 b853b9dbc0ba3d68a501d8badc4491f8108cd11b (commit) from 56e74908d17d740db0a376f354c21e6608e8af8d (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 b853b9dbc0ba3d68a501d8badc4491f8108cd11b Author: David Brownell <dbr...@us...> Date: Sun Feb 21 13:27:37 2010 -0800 Open the merge window for the 0.5.0 release cycle. Signed-off-by: David Brownell <dbr...@us...> diff --git a/NEWS b/NEWS index cbd5526..b39b3a8 100644 --- a/NEWS +++ b/NEWS @@ -1,90 +1,23 @@ This file includes highlights of the changes made in the -OpenOCD 0.4.0 source archive release. See the repository +OpenOCD 0.5.0 source archive release. See the repository history for details about what changed, including bugfixes and other issues not mentioned here. JTAG Layer: - Support KT-Link JTAG adapter. - Support USB-JTAG, Altera USB-Blaster and compatibles. Boundary Scan: Target Layer: - General - - Removed commands which have been obsolete for at least - a year (from both documentation and, sometimes, code). - - new "reset-assert" event, for systems without SRST - ARM - - supports "reset-assert" event (except on Cortex-M3) - - renamed "armv4_5" command prefix as "arm" - - recognize TrustZone "Secure Monitor" mode - - "arm regs" command output changed - - register names use "sp" not "r13" - - add top-level "mcr" and "mrc" commands, replacing - various core-specific operations - - basic semihosting support (ARM7/ARM9 only, for now) - ARM11 - - Should act much more like other ARM cores: - * Preliminary ETM and ETB hookup - * accelerated "flash erase_check" - * accelerated GDB memory checksum - * support "arm regs" command - * can access all core modes and registers - * watchpoint support - - Shares some core debug code with Cortex-A8 - Cortex-A8 - - Should act much more like other ARM cores: - * support "arm regs" command - * can access all core modes and registers - * watchpoint support - - Shares some core debug code with ARM11 - Cortex-M3 - - Exposed DWT registers like cycle counter - - vector_catch settings not clobbered by resets - - no longer interferes with firmware's fault handling - ETM, ETB - - "trigger_percent" command moved ETM --> ETB - - "etm trigger_debug" command added - MIPS - - use fastdata writes - Freescale DSP563xx cores (partial support) Flash Layer: - 'flash bank' and 'nand device' take <bank_name> as first argument. - With this, flash/NAND commands allow referencing banks by name: - - <bank_name>: reference the bank with its defined name - - <driver_name>[.N]: reference the driver's Nth bank - New 'nand verify' command to check bank against an image file. - The "flash erase_address" command now rejects partial sectors; - previously it would silently erase extra data. If you - want to erase the rest of the first and/or last sectors - instead of failing, you must pass an explicit "pad" flag. - New at91sam9 NAND controller driver. - New s3c64xx NAND controller driver. Board, Target, and Interface Configuration Scripts: - ARM9 - - ETM and ETB hookup for iMX2* targets - Add $HOME/.openocd to the search path. - Handle Rev C of LM3S811 eval boards. - - use "luminary-lm3s811.cfg" for older boards - - use "luminary.cfg" for RevC and newer Core Jim/TCL Scripting: - New 'usage' command to provide terse command help. - Improved command 'help' command output (sorted and indented). - Improved command handling: - - Most boolean settings now accept any of the following: - on/off, enable/disable, true/false, yes/no, 1/0 - - More error checking and reporting. Documentation: - New built-in command development documentation and primer. Build and Release: - Use --enable-doxygen-pdf to build PDF developer documentation. - Consider upgrading to libftdi 0.17 if you use that library; it - includes bugfixes which improve FT2232H support. For more details about what has changed since the last release, see the git repository history. With gitweb, you can browse that @@ -96,3 +29,4 @@ For older NEWS, see the NEWS files associated with each release For more information about contributing test reports, bug fixes, or new features and device support, please read the new Developer Manual (or the BUGS and PATCHES.txt files in the source archive). + diff --git a/NEWS b/NEWS-0.4.0 similarity index 100% copy from NEWS copy to NEWS-0.4.0 diff --git a/configure.in b/configure.in index 4681aeb..3b0a06d 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT([openocd], [0.4.0], +AC_INIT([openocd], [0.5.0-dev], [OpenOCD Mailing List <ope...@li...>]) AC_CONFIG_SRCDIR([src/openocd.c]) ----------------------------------------------------------------------- Summary of changes: NEWS | 70 +-------------------------------------------------- NEWS => NEWS-0.4.0 | 0 configure.in | 2 +- 3 files changed, 3 insertions(+), 69 deletions(-) copy NEWS => NEWS-0.4.0 (100%) hooks/post-receive -- Main OpenOCD repository |