From 0a13ca1a8a83119a4e1ffba13a6a8d1977591bc5 Mon Sep 17 00:00:00 2001 From: Christian Meusel Date: Mon, 15 Jul 2019 18:01:38 +0200 Subject: [PATCH 001/354] efm32: use device-specific MSC base for EFM32TG11B According to the reference manual it should be 0x40000000. Flashing (and booting) a firmware with this MSC base was successful. Change-Id: I739e67d36555b8170a3b8e26f54cf1c09ce8424b Signed-off-by: Christian Meusel Reviewed-on: http://openocd.zylin.com/5263 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/efm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c index 83d133ff6..245f856b5 100644 --- a/src/flash/nor/efm32.c +++ b/src/flash/nor/efm32.c @@ -166,7 +166,7 @@ static const struct efm32_family_data efm32_families[] = { { 89, "EFM32PG13B Pearl", .series = 1 }, { 91, "EFM32JG13B Jade", .series = 1 }, { 100, "EFM32GG11B Giant", .series = 1, .msc_regbase = 0x40000000 }, - { 103, "EFM32TG11B Tiny", .series = 1 }, + { 103, "EFM32TG11B Tiny", .series = 1, .msc_regbase = 0x40000000 }, { 120, "EZR32WG Wonder", .series = 0 }, { 121, "EZR32LG Leopard", .series = 0 }, { 122, "EZR32HG Happy", .series = 0, .page_size = 1024 }, From d214cadfef7ba75c7c52849c7946d32f0ad8b668 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Wed, 14 Nov 2018 11:55:09 -0800 Subject: [PATCH 002/354] Add wall clock timeout warning to mpsse_flush() I think that libusb_handle_events_timeout_completed is supposed to make progress or time out, but sometimes we hit a case where it makes no progress, and mpsse_flush() loops forever. This wall clock timeout notifies the user that this is going on. When I wrote this code, this bug would reproduce every hour or two, but right now it's not happening for me. Change-Id: I7eb66f43462298e263a48048aa0c8769095661eb Signed-off-by: Tim Newsome Reviewed-on: http://openocd.zylin.com/4767 Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- src/jtag/drivers/mpsse.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c index a881803ad..7488d9dd8 100644 --- a/src/jtag/drivers/mpsse.c +++ b/src/jtag/drivers/mpsse.c @@ -22,6 +22,7 @@ #include "mpsse.h" #include "helper/log.h" +#include "helper/time_support.h" #include /* Compatibility define for older libusb-1.0 */ @@ -888,6 +889,8 @@ int mpsse_flush(struct mpsse_ctx *ctx) } /* Polling loop, more or less taken from libftdi */ + int64_t start = timeval_ms(); + int64_t warn_after = 2000; while (!write_result.done || !read_result.done) { struct timeval timeout_usb; @@ -910,6 +913,13 @@ int mpsse_flush(struct mpsse_ctx *ctx) break; } } + + int64_t now = timeval_ms(); + if (now - start > warn_after) { + LOG_WARNING("Haven't made progress in mpsse_flush() for %" PRId64 + "ms.", now - start); + warn_after *= 2; + } } error_check: From 462c01206692ead0287107772146f6cc467129f9 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Tue, 6 Mar 2018 13:13:35 -0800 Subject: [PATCH 003/354] Add complete JTAG debug logging. Sample output, with default_interface_jtag_execute_queue replaced by dijeq to satisfy commit message line length check: Debug: 646 18 core.c:847 dijeq(): JTAG IR SCAN to RUN/IDLE Debug: 647 18 core.c:852 dijeq(): 5b out: 11 Debug: 648 18 core.c:847 dijeq(): JTAG DR SCAN to RUN/IDLE Debug: 649 18 core.c:852 dijeq(): 40b out: 4400000001 Debug: 650 18 core.c:857 dijeq(): 40b in: 4400000000 Signed-off-by: Tim Newsome Change-Id: I014e9e3a77755413b36edfcede2ab8f6aa08061b Reviewed-on: http://openocd.zylin.com/4451 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/core.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index 18956f24d..144cf94f7 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -836,7 +836,75 @@ int default_interface_jtag_execute_queue(void) return ERROR_FAIL; } - return jtag->execute_queue(); + int result = jtag->execute_queue(); + +#if !BUILD_ZY1000 + /* Only build this if we use a regular driver with a command queue. + * Otherwise jtag_command_queue won't be found at compile/link time. Its + * definition is in jtag/commands.c, which is only built/linked by + * jtag/Makefile.am if MINIDRIVER_DUMMY || !MINIDRIVER, but those variables + * aren't accessible here. */ + struct jtag_command *cmd = jtag_command_queue; + while (debug_level >= LOG_LVL_DEBUG && cmd) { + switch (cmd->type) { + case JTAG_SCAN: + LOG_DEBUG_IO("JTAG %s SCAN to %s", + cmd->cmd.scan->ir_scan ? "IR" : "DR", + tap_state_name(cmd->cmd.scan->end_state)); + for (int i = 0; i < cmd->cmd.scan->num_fields; i++) { + struct scan_field *field = cmd->cmd.scan->fields + i; + if (field->out_value) { + char *str = buf_to_str(field->out_value, field->num_bits, 16); + LOG_DEBUG_IO(" %db out: %s", field->num_bits, str); + free(str); + } + if (field->in_value) { + char *str = buf_to_str(field->in_value, field->num_bits, 16); + LOG_DEBUG_IO(" %db in: %s", field->num_bits, str); + free(str); + } + } + break; + case JTAG_TLR_RESET: + LOG_DEBUG_IO("JTAG TLR RESET to %s", + tap_state_name(cmd->cmd.statemove->end_state)); + break; + case JTAG_RUNTEST: + LOG_DEBUG_IO("JTAG RUNTEST %d cycles to %s", + cmd->cmd.runtest->num_cycles, + tap_state_name(cmd->cmd.runtest->end_state)); + break; + case JTAG_RESET: + { + const char *reset_str[3] = { + "leave", "deassert", "assert" + }; + LOG_DEBUG_IO("JTAG RESET %s TRST, %s SRST", + reset_str[cmd->cmd.reset->trst + 1], + reset_str[cmd->cmd.reset->srst + 1]); + } + break; + case JTAG_PATHMOVE: + LOG_DEBUG_IO("JTAG PATHMOVE (TODO)"); + break; + case JTAG_SLEEP: + LOG_DEBUG_IO("JTAG SLEEP (TODO)"); + break; + case JTAG_STABLECLOCKS: + LOG_DEBUG_IO("JTAG STABLECLOCKS (TODO)"); + break; + case JTAG_TMS: + LOG_DEBUG_IO("JTAG TMS (TODO)"); + break; + default: + LOG_ERROR("Unknown JTAG command: %d", cmd->type); + break; + } + cmd = cmd->next; + } +#endif + + return result; } void jtag_execute_queue_noclear(void) @@ -1107,7 +1175,8 @@ static int jtag_examine_chain(void) if ((idcode & 1) == 0) { /* Zero for LSB indicates a device in bypass */ - LOG_INFO("TAP %s does not have IDCODE", tap->dotted_name); + LOG_INFO("TAP %s does not have valid IDCODE (idcode=0x%x)", + tap->dotted_name, idcode); tap->hasidcode = false; tap->idcode = 0; From b4a7ff291c3636eb5f6aa224476268775aceecad Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Sep 2019 13:49:17 +0200 Subject: [PATCH 004/354] doc: emphasize the role of 'reset init' before flash commands Change-Id: I4a4061ad0fa6e5dfb1e33f01d62145ca9bf12148 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5304 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index c5a926ca8..bc77469c8 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4949,6 +4949,20 @@ flash drivers can distinguish between probing and autoprobing, but most don't bother. @end deffn +@section Preparing a Target before Flash Programming + +The target device should be in well defined state before the flash programming +begins. + +@emph{Always issue} @command{reset init} before @ref{flashprogrammingcommands,,Flash Programming Commands}. +Do not issue another @command{reset} or @command{reset halt} or @command{resume} +until the programming session is finished. + +If you use @ref{programmingusinggdb,,Programming using GDB}, +the target is prepared automatically in the event gdb-flash-erase-start + +The jimtcl script @command{program} calls @command{reset init} explicitly. + @section Erasing, Reading, Writing to Flash @cindex flash erasing @cindex flash reading @@ -7503,7 +7517,7 @@ change any behavior. @chapter Flash Programming OpenOCD implements numerous ways to program the target flash, whether internal or external. -Programming can be achieved by either using GDB @ref{programmingusinggdb,,Programming using GDB}, +Programming can be achieved by either using @ref{programmingusinggdb,,Programming using GDB}, or using the commands given in @ref{flashprogrammingcommands,,Flash Programming Commands}. @*To simplify using the flash commands directly a jimtcl script is available that handles the programming and verify stage. From 51ce53d044bc1f60519c0b24c6afe845f66f25e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Thu, 29 Aug 2019 09:07:06 +0200 Subject: [PATCH 005/354] src/flash/startup.tcl: Add preverify to program command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The preverify option allows to check whether flashing is necessary. If the target is flashed often/automatically this can save time and preserve the flash. This is expecially helpful in CI environments. Change-Id: Iead0a269e1a772b751d4dd9e8b53b2fecc874624 Signed-off-by: Moritz 'Morty' Strübe Reviewed-on: http://openocd.zylin.com/5292 Tested-by: jenkins Reviewed-by: Paul Fertser Reviewed-by: Spencer Oliver Reviewed-by: Tarek BOCHKATI --- doc/openocd.texi | 3 +- src/flash/startup.tcl | 78 ++++++++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index bc77469c8..440f43454 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5138,7 +5138,7 @@ command or the flash driver then it defaults to 0xff. @end deffn @anchor{program} -@deffn Command {program} filename [verify] [reset] [exit] [offset] +@deffn Command {program} filename [preverify] [verify] [reset] [exit] [offset] This is a helper script that simplifies using OpenOCD as a standalone programmer. The only required parameter is @option{filename}, the others are optional. @xref{Flash Programming}. @@ -7528,6 +7528,7 @@ The script is executed as follows and by default the following actions will be p @item 'init' is executed. @item 'reset init' is called to reset and halt the target, any 'reset init' scripts are executed. @item @code{flash write_image} is called to erase and write any flash using the filename given. +@item If the @option{preverify} parameter is given, the target is "verified" first and only flashed if this fails. @item @code{verify_image} is called if @option{verify} parameter is given. @item @code{reset run} is called if @option{reset} parameter is given. @item OpenOCD is shutdown if @option{exit} parameter is given. diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl index ff053ae1b..de52e2060 100644 --- a/src/flash/startup.tcl +++ b/src/flash/startup.tcl @@ -17,9 +17,12 @@ proc program_error {description exit} { proc program {filename args} { set exit 0 + set needsflash 1 foreach arg $args { - if {[string equal $arg "verify"]} { + if {[string equal $arg "preverify"]} { + set preverify 1 + } elseif {[string equal $arg "verify"]} { set verify 1 } elseif {[string equal $arg "reset"]} { set reset 1 @@ -30,6 +33,15 @@ proc program {filename args} { } } + # Set variables + set filename \{$filename\} + if {[info exists address]} { + set flash_args "$filename $address" + } else { + set flash_args "$filename" + } + + # make sure init is called if {[catch {init}] != 0} { program_error "** OpenOCD init failed **" 1 @@ -40,40 +52,46 @@ proc program {filename args} { program_error "** Unable to reset target **" $exit } + # Check whether programming is needed + if {[info exists preverify]} { + echo "**pre-verifying**" + if {[catch {eval verify_image $flash_args}] == 0} { + echo "**Verified OK - No flashing**" + set needsflash 0 + } + } + # start programming phase - echo "** Programming Started **" - set filename \{$filename\} - if {[info exists address]} { - set flash_args "$filename $address" - } else { - set flash_args "$filename" + if {$needsflash == 1} { + echo "** Programming Started **" + + if {[catch {eval flash write_image erase $flash_args}] == 0} { + echo "** Programming Finished **" + if {[info exists verify]} { + # verify phase + echo "** Verify Started **" + if {[catch {eval verify_image $flash_args}] == 0} { + echo "** Verified OK **" + } else { + program_error "** Verify Failed **" $exit + } + } + } else { + program_error "** Programming Failed **" $exit + } } - if {[catch {eval flash write_image erase $flash_args}] == 0} { - echo "** Programming Finished **" - if {[info exists verify]} { - # verify phase - echo "** Verify Started **" - if {[catch {eval verify_image $flash_args}] == 0} { - echo "** Verified OK **" - } else { - program_error "** Verify Failed **" $exit - } + if {[info exists reset]} { + # reset target if requested + if {$exit == 1} { + # also disable target polling, we are shutting down anyway + poll off } - - if {[info exists reset]} { - # reset target if requested - if {$exit == 1} { - # also disable target polling, we are shutting down anyway - poll off - } - echo "** Resetting Target **" - reset run - } - } else { - program_error "** Programming Failed **" $exit + echo "** Resetting Target **" + reset run } + if {$exit == 1} { shutdown } @@ -81,7 +99,7 @@ proc program {filename args} { } add_help_text program "write an image to flash, address is only required for binary images. verify, reset, exit are optional" -add_usage_text program " \[address\] \[verify\] \[reset\] \[exit\]" +add_usage_text program " \[address\] \[pre-verify\] \[verify\] \[reset\] \[exit\]" # stm32f0x uses the same flash driver as the stm32f1x # this alias enables the use of either name. From 3a50bb46dc084999f6f7aee8913858ccced49db4 Mon Sep 17 00:00:00 2001 From: Al Dyrius Date: Wed, 25 Sep 2019 23:39:05 -0600 Subject: [PATCH 006/354] Update FTDI C232HM cfg, and add two new cfgs from cable modem research Change-Id: Idbeffcd5ff4380b1e7c9fd5ef6ba3ca77cc22d99 Signed-off-by: Al Dyrius Reviewed-on: http://openocd.zylin.com/5307 Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- tcl/board/kc100.cfg | 31 ++++++++++++++++++++++++ tcl/interface/ftdi/c232hm.cfg | 45 +++++++++++++++++++++++++++++++++-- tcl/target/tnetc4401.cfg | 17 +++++++++++++ 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 tcl/board/kc100.cfg create mode 100644 tcl/target/tnetc4401.cfg diff --git a/tcl/board/kc100.cfg b/tcl/board/kc100.cfg new file mode 100644 index 000000000..1d383bef5 --- /dev/null +++ b/tcl/board/kc100.cfg @@ -0,0 +1,31 @@ +# Knovative KC-100 cable modem + +# TNETC4401PYP, 208-QFP U3 +source [find target/tnetc4401.cfg] + +# 14-pin EJTAG on JP1. Standard pinout, 1-3-5-7-9-11 = nTRST-TDI-TDO-TMS-TCK-nSRST. Use 2 for GND. +# Was initially disabled in hardware; had to add a solder bridge reenabling R124, R125 on back. +reset_config trst_and_srst separate + +# 16Mb Intel CFI flash. Note this CPU has an internal ROM at 0x1FC0000 (phys) for cold boot. +# All that really does is some minimal checks before jumping to external flash at 0x00000000 phys. +# That is remapped to 0xB0000000 uncached, 0x90000000 cached. +flash bank intel cfi 0xB0000000 0x200000 2 2 $_TARGETNAME + +# Perform this after a clean reboot, halt, and reset init (which should also leave it halted). +proc kc100_dump_flash {} { + echo "Probing 48 TSOP Intel CFI flash chip (2MB)..." + flash probe intel + echo "Dumping 2MB flash chip to flashdump.bin. + flash read_bank 0 flashdump.bin 0 0x200000 +} + +#TODO figure out memory init sequence to be able to dump from cached segment instead + +# There is also a serial console on JP2, 3-5-6 = TX-RX-GND. 9600/8/N/1. + +# Possibly of note, this modem's ancient ethernet port does not support Auto-MDIX. + +# This modem in many ways appears to be essentially a clone of the SB5120. See usbjtag.com. +# The firmware/OS is also susceptible to many of the same procedures in "Hacking the Cable Modem" +# by DerEngel (Ryan Harris), available from No Starch Press. diff --git a/tcl/interface/ftdi/c232hm.cfg b/tcl/interface/ftdi/c232hm.cfg index 387abbb05..4f623e0f8 100644 --- a/tcl/interface/ftdi/c232hm.cfg +++ b/tcl/interface/ftdi/c232hm.cfg @@ -1,4 +1,3 @@ -# # FTDI USB Hi-Speed to MPSSE Cable # # http://www.ftdichip.com/Products/Cables/USBMPSSE.htm @@ -6,10 +5,52 @@ # C232HM-DDHSL-0 and C232HM-EDSL-0 provide 3.3V and 5V on pin 1 (Red), # respectively. # +# Adapter: http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_C232HM_MPSSE_CABLE.PDF +# Chip: http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf +# See pinout/colors at end of this file. +# +# Tech notes: +# http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf +# http://www.ftdichip.com/Support/Documents/AppNotes/AN_129_FTDI_Hi_Speed_USB_To_JTAG_Example.pdf interface ftdi #ftdi_device_desc "C232HM-DDHSL-0" #ftdi_device_desc "C232HM-EDHSL-0" + +# Common PID for FT232H ftdi_vid_pid 0x0403 0x6014 -ftdi_layout_init 0x0008 0x000b +# Layout +# High data byte 0x40 configures red LED on ACBUS6 initially high (unlit, since active-low) +# Low data byte 0x08 configures TMS on ACBUS3 initially high (asserted); TCK, TDI low +# High direction byte 0x40 configures red LED on ACBUS6 as high (output) +# Low direction byte 0x0b configures TDO on ACBUS2 as low (input) +ftdi_layout_init 0x4008 0x400b + +# ---A*BUS-------CCCCCCCC|DDDDDDDD +# --------\______76543210|76543210 +# LED 0x4000 = 01000000|00000000 = ACBUS6 +#GPIOL0 0x0010 = 00000000|00010000 = ADBUS4 +#GPIOL1 0x0020 = 00000000|00100000 = ADBUS5 +#GPIOL2 0x0040 = 00000000|01000000 = ADBUS6 +#GPIOL3 0x0080 = 00000000|10000000 = ADBUS7 +# -ndata treats the LED as active-low for expected behavior (toggle when transferring) +ftdi_layout_signal LED -ndata 0x4000 +# Available for aliasing as desired +ftdi_layout_signal GPIOL0 -data 0x0010 -oe 0x0010 +ftdi_layout_signal GPIOL1 -data 0x0020 -oe 0x0020 +ftdi_layout_signal GPIOL2 -data 0x0040 -oe 0x0040 +ftdi_layout_signal GPIOL3 -data 0x0080 -oe 0x0080 + +# C232HM FT232H JTAG/Other +# Num Color Name Func +# 1 Red VCC Optionally, can power the board if it is not using its own power supply. +# 2 Orange ADBUS0 TCK +# 3 Yellow ADBUS1 TDI +# 4 Green ADBUS2 TDO +# 5 Brown ADBUS3 TMS +# 6 Grey ADBUS4 GPIOL0 +# 7 Purple ADBUS5 GPIOL1 +# 8 White ADBUS6 GPIOL2 +# 9 Blue ADBUS7 GPIOL3 +# 10 Black GND Connect to ground diff --git a/tcl/target/tnetc4401.cfg b/tcl/target/tnetc4401.cfg new file mode 100644 index 000000000..48f754527 --- /dev/null +++ b/tcl/target/tnetc4401.cfg @@ -0,0 +1,17 @@ +# Texas Instruments (TI) TNETC4401, MIPS32 DOCSIS-tailored SoC (4Kc-based) +# Used in Knovative KC-100 and Motorola Surfboard SB5120 cable modems. +# Datasheet: https://brezn.muc.ccc.de/~mazzoo/DOCSIS/tnetc4401.pdf +transport select jtag +set _TARGETNAME tnetc4401 +set _CPUTAPID 0x0000100f +jtag newtap $_TARGETNAME tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID +target create $_TARGETNAME mips_m4k -chain-position $_TARGETNAME.tap -endian big + +# May need to halt manually before calling reset init +$_TARGETNAME configure -event reset-init { + halt + echo "Attempting to disable watchdog..." + mwb phys 0xa8610b00 0 256 + halt + wait_halt +} From f545044c2a37a44a51e2a07bdcd52df4eed86a4a Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Wed, 13 Jan 2016 20:39:28 +0100 Subject: [PATCH 007/354] target: Switch to target_read_buffer() in verify_image fallback The current code checks the count to determine whether to read bytes or words. However it fails to consider whether the base address is suitably aligned. Instead use the target_read_buffer() function which is for exactly this purpose and generates optimal accesses with natural alignment. Change-Id: I32ab5417890ee2219902df1529bc220fe353b4c7 Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/3217 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/target/target.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 51fdff342..03b6f4eb2 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -3636,14 +3636,7 @@ static COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode ver data = malloc(buf_cnt); - /* Can we use 32bit word accesses? */ - int size = 1; - int count = buf_cnt; - if ((count % 4) == 0) { - size *= 4; - count /= 4; - } - retval = target_read_memory(target, image.sections[i].base_address, size, count, data); + retval = target_read_buffer(target, image.sections[i].base_address, buf_cnt, data); if (retval == ERROR_OK) { uint32_t t; for (t = 0; t < buf_cnt; t++) { From 3e7cfc67099086481fe24da0a30d26bd8d9f74a9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 14 Jul 2016 16:32:10 +0300 Subject: [PATCH 008/354] stm32l0|l1: don't corrupt RCC registers instead of overwriting Reset settings, let's read-modify-write RCC registers. Change-Id: I21b7e26e6007d3c3d73803c681c980c6947f5910 Signed-off-by: Felipe Balbi Reviewed-on: http://openocd.zylin.com/3601 Tested-by: jenkins Reviewed-by: Spencer Oliver --- tcl/target/stm32l0.cfg | 7 +++++-- tcl/target/stm32l1.cfg | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tcl/target/stm32l0.cfg b/tcl/target/stm32l0.cfg index ec5d5463e..e09af8001 100644 --- a/tcl/target/stm32l0.cfg +++ b/tcl/target/stm32l0.cfg @@ -61,10 +61,13 @@ proc stm32l0_enable_HSI16 {} { echo "STM32L0: Enabling HSI16" # Set HSI16ON in RCC_CR (leave MSI enabled) - mww 0x40021000 0x00000101 + mmw 0x40021000 0x00000101 0 # Set HSI16 as SYSCLK (RCC_CFGR) - mww 0x4002100c 0x00000001 + mmw 0x4002100c 0x00000001 0 + + # Wait until System clock switches to HSI16 + while { ([ mrw 0x4002100c ] & 0x0c) != 0x04 } { } # Increase speed adapter_khz 2500 diff --git a/tcl/target/stm32l1.cfg b/tcl/target/stm32l1.cfg index 054fa9b74..0933151a0 100644 --- a/tcl/target/stm32l1.cfg +++ b/tcl/target/stm32l1.cfg @@ -73,10 +73,10 @@ proc stm32l_enable_HSI {} { echo "STM32L: Enabling HSI" # Set HSION in RCC_CR - mww 0x40023800 0x00000101 + mmw 0x40023800 0x00000101 0 # Set HSI as SYSCLK - mww 0x40023808 0x00000001 + mmw 0x40023808 0x00000001 0 # Increase JTAG speed adapter_khz 2000 From 0bb011f004879c4ac83512ac909359e1093ffdc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20F=C3=A4rber?= Date: Sun, 14 Jan 2018 23:48:37 +0100 Subject: [PATCH 009/354] tcl/target: Add Infineon TLE987x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepare a config for Infineon TLE9879. Change-Id: Ic667ae822fd514cac365993bc3f39b4185f1a118 Signed-off-by: Andreas Färber Reviewed-on: http://openocd.zylin.com/4339 Tested-by: jenkins Reviewed-by: Matthias Welwarsky --- tcl/target/infineon/tle987x.cfg | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 tcl/target/infineon/tle987x.cfg diff --git a/tcl/target/infineon/tle987x.cfg b/tcl/target/infineon/tle987x.cfg new file mode 100644 index 000000000..00cb1c034 --- /dev/null +++ b/tcl/target/infineon/tle987x.cfg @@ -0,0 +1,36 @@ +# +# Infineon TLE987x family (Arm Cortex-M3 @ up to 40 MHz) +# + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME tle987x +} + +source [find target/swj-dp.tcl] + +if { [info exists CPU_SWD_TAPID] } { + set _CPU_SWD_TAPID $CPU_SWD_TAPID +} else { + set _CPU_SWD_TAPID 0x2BA01477 +} + +if { [using_jtag] } { + # JTAG not supported, only SWD + set _CPU_TAPID 0 +} else { + set _CPU_TAPID $_CPU_SWD_TAPID +} + +swj_newdap $_CHIPNAME dap -irlen 4 -expected-id $_CPU_TAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap + +if { ![using_hla] } { + cortex_m reset_config sysresetreq +} + +adapter_khz 1000 From 3afb357934217ccd5889f8ffc7f6e9d65b3162f1 Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Wed, 21 Nov 2018 14:09:39 +0100 Subject: [PATCH 010/354] nrf5: Fix misuse of flash bank number Make driver_priv point directly into the corresponding chip bank structure and add a pointer to it to get back to its chip when it's needed. This removes the need to keep track of any bank number, either global or chip- local. In addition, it simplifies the cases where the chip structure was just used to access the chip bank fields; now they are directly accessible. Change-Id: Iaa353cd4fa7d8ff94c2ef69028c7cb32fade0420 Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/4775 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/nrf5.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 4041bfbe4..78d52b877 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -111,7 +111,8 @@ struct nrf5_info { uint32_t code_page_size; uint32_t refcount; - struct { + struct nrf5_bank { + struct nrf5_info *chip; bool probed; int (*write) (struct flash_bank *bank, struct nrf5_info *chip, @@ -219,11 +220,11 @@ static const struct nrf5_device_spec nrf5_known_devices_table[] = { static int nrf5_bank_is_probed(struct flash_bank *bank) { - struct nrf5_info *chip = bank->driver_priv; + struct nrf5_bank *nbank = bank->driver_priv; - assert(chip != NULL); + assert(nbank != NULL); - return chip->bank[bank->bank_number].probed; + return nbank->probed; } static int nrf5_probe(struct flash_bank *bank); @@ -234,7 +235,8 @@ static int nrf5_get_probed_chip_if_halted(struct flash_bank *bank, struct nrf5_i return ERROR_TARGET_NOT_HALTED; } - *chip = bank->driver_priv; + struct nrf5_bank *nbank = bank->driver_priv; + *chip = nbank->chip; int probed = nrf5_bank_is_probed(bank); if (probed < 0) @@ -376,7 +378,8 @@ static int nrf5_protect_check(struct flash_bank *bank) if (bank->base == NRF5_UICR_BASE) return ERROR_OK; - struct nrf5_info *chip = bank->driver_priv; + struct nrf5_bank *nbank = bank->driver_priv; + struct nrf5_info *chip = nbank->chip; assert(chip != NULL); @@ -462,7 +465,8 @@ static int nrf5_probe(struct flash_bank *bank) { uint32_t hwid; int res; - struct nrf5_info *chip = bank->driver_priv; + struct nrf5_bank *nbank = bank->driver_priv; + struct nrf5_info *chip = nbank->chip; res = target_read_u32(chip->target, NRF5_FICR_CONFIGID, &hwid); if (res != ERROR_OK) { @@ -740,7 +744,8 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t offset, const ui static int nrf5_write_pages(struct flash_bank *bank, uint32_t start, uint32_t end, const uint8_t *buffer) { int res = ERROR_FAIL; - struct nrf5_info *chip = bank->driver_priv; + struct nrf5_bank *nbank = bank->driver_priv; + struct nrf5_info *chip = nbank->chip; assert(start % chip->code_page_size == 0); assert(end % chip->code_page_size == 0); @@ -872,18 +877,20 @@ static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { int res; + struct nrf5_bank *nbank = bank->driver_priv; struct nrf5_info *chip; res = nrf5_get_probed_chip_if_halted(bank, &chip); if (res != ERROR_OK) return res; - return chip->bank[bank->bank_number].write(bank, chip, buffer, offset, count); + return nbank->write(bank, chip, buffer, offset, count); } static void nrf5_free_driver_priv(struct flash_bank *bank) { - struct nrf5_info *chip = bank->driver_priv; + struct nrf5_bank *nbank = bank->driver_priv; + struct nrf5_info *chip = nbank->chip; if (chip == NULL) return; @@ -897,13 +904,11 @@ static void nrf5_free_driver_priv(struct flash_bank *bank) FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) { static struct nrf5_info *chip; + struct nrf5_bank *nbank = NULL; switch (bank->base) { case NRF5_FLASH_BASE: - bank->bank_number = 0; - break; case NRF5_UICR_BASE: - bank->bank_number = 1; break; default: LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base); @@ -921,16 +926,20 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) switch (bank->base) { case NRF5_FLASH_BASE: - chip->bank[bank->bank_number].write = nrf5_code_flash_write; + nbank = &chip->bank[0]; + nbank->write = nrf5_code_flash_write; break; case NRF5_UICR_BASE: - chip->bank[bank->bank_number].write = nrf5_uicr_flash_write; + nbank = &chip->bank[1]; + nbank->write = nrf5_uicr_flash_write; break; } + assert(nbank != NULL); chip->refcount++; - chip->bank[bank->bank_number].probed = false; - bank->driver_priv = chip; + nbank->chip = chip; + nbank->probed = false; + bank->driver_priv = nbank; return ERROR_OK; } From 03beb01239a8ca02787cb99d19401b1974fe41c4 Mon Sep 17 00:00:00 2001 From: Piotr Kasprzyk Date: Sat, 8 Dec 2018 03:27:51 +0100 Subject: [PATCH 011/354] Fix wrong end-of-region calculation Correct check for end-of-region is: $BASE + $LEN > $ADDRESS And it is currently (wrongly) calculated as: $ADDRESS > $BASE - $LEN Change-Id: If10bfee19b0c7dbc085731ac1eda943f5d8a36a3 Signed-off-by: Piotr Kasprzyk Reviewed-on: http://openocd.zylin.com/4798 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Spencer Oliver --- tcl/memory.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcl/memory.tcl b/tcl/memory.tcl index 83c96d6c9..a7f5b9ac4 100644 --- a/tcl/memory.tcl +++ b/tcl/memory.tcl @@ -58,7 +58,7 @@ set ACCESS_WIDTH_ANY [expr $ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_3 set UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE proc iswithin { ADDRESS BASE LEN } { - return [expr ((($ADDRESS - $BASE) > 0) && (($ADDRESS - $BASE + $LEN) > 0))] + return [expr ((($ADDRESS - $BASE) > 0) && (($BASE + $LEN - $ADDRESS) > 0))] } proc address_info { ADDRESS } { From 5f42124a40e8ccbc1b5db3a8898d24408be22c62 Mon Sep 17 00:00:00 2001 From: Bohdan Tymkiv Date: Tue, 26 Feb 2019 11:45:40 +0200 Subject: [PATCH 012/354] adi_v5_jtag: avoid RAM exhaustion by limiting jtag queue size Issue has been found when I tried to read 64 MiB QSPI flash bank. Bank is memory mapped, default_flash_read() is used for 'flash read_bank' command. OpenOCD consumed as much as 6.8 GiB of RAM during this process. Investigation showed that this happens because JTAG queue is not limited in any way. OpenOCD queues 16 millions of AP reads allocating all corresponding data structures. Most of this memory is allocated in: cmd_queue_alloc (commands.c) - 4.2 GiB dap_cmd_new (adi_v5_jtag.c) - 2.25GiB This patch implements a pool of "struct dap_cmd" objects using linked list. Objects are taken from a pool in "dap_cmd_new()" and returned to the pool when they are not needed. Size of the pool is limited to 64K of objects, JTAG queue is forcibly executed when this limit is reached. Checked with Valgrind and Clang analyzer - no new warnings. Change-Id: I5aaaecce5ed71414f7965a2598f49742f6a6b2b5 Signed-off-by: Bohdan Tymkiv Reviewed-on: http://openocd.zylin.com/4948 Tested-by: jenkins Reviewed-by: Matthias Welwarsky --- src/target/adi_v5_jtag.c | 115 ++++++++++++++++++++++++++++++--------- src/target/arm_adi_v5.h | 6 ++ src/target/arm_dap.c | 1 + 3 files changed, 97 insertions(+), 25 deletions(-) diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c index a3867e191..df8113492 100644 --- a/src/target/adi_v5_jtag.c +++ b/src/target/adi_v5_jtag.c @@ -139,6 +139,13 @@ struct dap_cmd { uint8_t outvalue_buf[4]; }; +#define MAX_DAP_COMMAND_NUM 65536 + +struct dap_cmd_pool { + struct list_head lh; + struct dap_cmd cmd; +} dap_cmd_pool; + static void log_dap_cmd(const char *header, struct dap_cmd *el) { #ifdef DEBUG_WAIT @@ -153,32 +160,73 @@ static void log_dap_cmd(const char *header, struct dap_cmd *el) #endif } -static struct dap_cmd *dap_cmd_new(uint8_t instr, +static int jtag_limit_queue_size(struct adiv5_dap *dap) +{ + if (dap->cmd_pool_size < MAX_DAP_COMMAND_NUM) + return ERROR_OK; + + return dap_run(dap); +} + +static struct dap_cmd *dap_cmd_new(struct adiv5_dap *dap, uint8_t instr, uint8_t reg_addr, uint8_t RnW, uint8_t *outvalue, uint8_t *invalue, uint32_t memaccess_tck) { - struct dap_cmd *cmd; - cmd = (struct dap_cmd *)calloc(1, sizeof(struct dap_cmd)); - if (cmd != NULL) { - INIT_LIST_HEAD(&cmd->lh); - cmd->instr = instr; - cmd->reg_addr = reg_addr; - cmd->RnW = RnW; - if (outvalue != NULL) - memcpy(cmd->outvalue_buf, outvalue, 4); - cmd->invalue = (invalue != NULL) ? invalue : cmd->invalue_buf; - cmd->memaccess_tck = memaccess_tck; + struct dap_cmd_pool *pool = NULL; + + if (list_empty(&dap->cmd_pool)) { + pool = calloc(1, sizeof(struct dap_cmd_pool)); + if (pool == NULL) + return NULL; + } else { + pool = list_first_entry(&dap->cmd_pool, struct dap_cmd_pool, lh); + list_del(&pool->lh); } + INIT_LIST_HEAD(&pool->lh); + dap->cmd_pool_size++; + + struct dap_cmd *cmd = &pool->cmd; + INIT_LIST_HEAD(&cmd->lh); + cmd->instr = instr; + cmd->reg_addr = reg_addr; + cmd->RnW = RnW; + if (outvalue != NULL) + memcpy(cmd->outvalue_buf, outvalue, 4); + cmd->invalue = (invalue != NULL) ? invalue : cmd->invalue_buf; + cmd->memaccess_tck = memaccess_tck; + return cmd; } -static void flush_journal(struct list_head *lh) +static void dap_cmd_release(struct adiv5_dap *dap, struct dap_cmd *cmd) +{ + struct dap_cmd_pool *pool = container_of(cmd, struct dap_cmd_pool, cmd); + if (dap->cmd_pool_size > MAX_DAP_COMMAND_NUM) + free(pool); + else + list_add(&pool->lh, &dap->cmd_pool); + + dap->cmd_pool_size--; +} + +static void flush_journal(struct adiv5_dap *dap, struct list_head *lh) { struct dap_cmd *el, *tmp; + list_for_each_entry_safe(el, tmp, lh, lh) { + list_del(&el->lh); + dap_cmd_release(dap, el); + } +} + +static void jtag_quit(struct adiv5_dap *dap) +{ + struct dap_cmd_pool *el, *tmp; + struct list_head *lh = &dap->cmd_pool; + list_for_each_entry_safe(el, tmp, lh, lh) { list_del(&el->lh); free(el); @@ -273,7 +321,7 @@ static int adi_jtag_dp_scan(struct adiv5_dap *dap, struct dap_cmd *cmd; int retval; - cmd = dap_cmd_new(instr, reg_addr, RnW, outvalue, invalue, memaccess_tck); + cmd = dap_cmd_new(dap, instr, reg_addr, RnW, outvalue, invalue, memaccess_tck); if (cmd != NULL) cmd->dp_select = dap->select; else @@ -415,7 +463,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) * To complete the READ, we just keep polling RDBUFF * until the WAIT condition clears */ - tmp = dap_cmd_new(JTAG_DP_DPACC, + tmp = dap_cmd_new(dap, JTAG_DP_DPACC, DP_RDBUFF, DPAP_READ, NULL, NULL, 0); if (tmp == NULL) { retval = ERROR_JTAG_DEVICE_ERROR; @@ -459,7 +507,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) } /* we're done with this command, release it */ - free(tmp); + dap_cmd_release(dap, tmp); if (retval != ERROR_OK) goto done; @@ -479,7 +527,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) } /* we're done with the journal, flush it */ - flush_journal(&dap->cmd_journal); + flush_journal(dap, &dap->cmd_journal); /* check for overrun condition in the last batch of transactions */ if (found_wait) { @@ -494,7 +542,7 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) /* restore SELECT register first */ if (!list_empty(&replay_list)) { el = list_first_entry(&replay_list, struct dap_cmd, lh); - tmp = dap_cmd_new(JTAG_DP_DPACC, + tmp = dap_cmd_new(dap, JTAG_DP_DPACC, DP_SELECT, DPAP_WRITE, (uint8_t *)&el->dp_select, NULL, 0); if (tmp == NULL) { retval = ERROR_JTAG_DEVICE_ERROR; @@ -545,8 +593,8 @@ static int jtagdp_overrun_check(struct adiv5_dap *dap) } done: - flush_journal(&replay_list); - flush_journal(&dap->cmd_journal); + flush_journal(dap, &replay_list); + flush_journal(dap, &dap->cmd_journal); return retval; } @@ -595,7 +643,7 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap) } done: - flush_journal(&dap->cmd_journal); + flush_journal(dap, &dap->cmd_journal); return retval; } @@ -618,7 +666,11 @@ static int jtag_check_reconnect(struct adiv5_dap *dap) static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data) { - int retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC, reg, + int retval = jtag_limit_queue_size(dap); + if (retval != ERROR_OK) + return retval; + + retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC, reg, DPAP_READ, 0, dap->last_read, 0, NULL); dap->last_read = data; return retval; @@ -627,7 +679,11 @@ static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg, static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg, uint32_t data) { - int retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC, + int retval = jtag_limit_queue_size(dap); + if (retval != ERROR_OK) + return retval; + + retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC, reg, DPAP_WRITE, data, dap->last_read, 0, NULL); dap->last_read = NULL; return retval; @@ -650,7 +706,11 @@ static int jtag_ap_q_bankselect(struct adiv5_ap *ap, unsigned reg) static int jtag_ap_q_read(struct adiv5_ap *ap, unsigned reg, uint32_t *data) { - int retval = jtag_check_reconnect(ap->dap); + int retval = jtag_limit_queue_size(ap->dap); + if (retval != ERROR_OK) + return retval; + + retval = jtag_check_reconnect(ap->dap); if (retval != ERROR_OK) return retval; @@ -668,7 +728,11 @@ static int jtag_ap_q_read(struct adiv5_ap *ap, unsigned reg, static int jtag_ap_q_write(struct adiv5_ap *ap, unsigned reg, uint32_t data) { - int retval = jtag_check_reconnect(ap->dap); + int retval = jtag_limit_queue_size(ap->dap); + if (retval != ERROR_OK) + return retval; + + retval = jtag_check_reconnect(ap->dap); if (retval != ERROR_OK) return retval; @@ -725,4 +789,5 @@ const struct dap_ops jtag_dp_ops = { .queue_ap_abort = jtag_ap_q_abort, .run = jtag_dp_run, .sync = jtag_dp_sync, + .quit = jtag_quit, }; diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 6e2d8a182..ee04d4177 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -234,6 +234,12 @@ struct adiv5_dap { /* dap transaction list for WAIT support */ struct list_head cmd_journal; + /* pool for dap_cmd objects */ + struct list_head cmd_pool; + + /* number of dap_cmd objects in the pool */ + size_t cmd_pool_size; + struct jtag_tap *tap; /* Control config */ uint32_t dp_ctrl_stat; diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index fbcfe0d4d..0f2957804 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -59,6 +59,7 @@ static void dap_instance_init(struct adiv5_dap *dap) dap->ap[i].csw_default = CSW_AHB_DEFAULT; } INIT_LIST_HEAD(&dap->cmd_journal); + INIT_LIST_HEAD(&dap->cmd_pool); } const char *adiv5_dap_name(struct adiv5_dap *self) From 5dc5ed571435c63f274f94ef89e20face012df08 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 27 Apr 2019 15:52:52 +0200 Subject: [PATCH 013/354] target/cortex_a: use aligned accesses for read/write cpu memory slow Armv7a is able to read and write memory at un-aligned address, but only when bit SCTLR.A (Alignment check enable) is zero and the address belongs to a memory space with attribute "Normal" (see [1] chapter A3.2.1 "Unaligned data access"). In all the other cases the memory access will trigger an alignment fault data abort exception. Memory attributes are explained in [1] chapter A3.5 "Memory types and attributes and the memory order model". Disabling the MMU cause a change in memory attribute, as explained in [1] chapter B3.2 "The effects of disabling MMUs on VMSA behavior". This can cause several issues. e.g. a SW breakpoint on un-aligned 4-byte Thumb instruction, set when MMU is on, can be impossible to remove when MMU turns off. While is possible to check all the possible conditions before an un-aligned memory access, it's clearly more maintainable to skip such complexity and only perform aligned accesses. Check the alignment and eventually modify the data size before calling the functions cortex_a_{read,write}_cpu_memory_slow(). Change the comment in the two functions above to comply with the new behaviour. [1] ARM DDI 0406C.d - "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition" Change-Id: I57b4c11e7fa7e78aaaaee4406a5734b48db740ae Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5138 Tested-by: jenkins Reviewed-by: Matthias Welwarsky --- src/target/cortex_a.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index b3a8a41d0..3ed2481ba 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1893,7 +1893,8 @@ static int cortex_a_write_cpu_memory_slow(struct target *target, { /* Writes count objects of size size from *buffer. Old value of DSCR must * be in *dscr; updated to new value. This is slow because it works for - * non-word-sized objects and (maybe) unaligned accesses. If size == 4 and + * non-word-sized objects. Avoid unaligned accesses as they do not work + * on memory address space without "Normal" attribute. If size == 4 and * the address is aligned, cortex_a_write_cpu_memory_fast should be * preferred. * Preconditions: @@ -2050,7 +2051,22 @@ static int cortex_a_write_cpu_memory(struct target *target, /* We are doing a word-aligned transfer, so use fast mode. */ retval = cortex_a_write_cpu_memory_fast(target, count, buffer, &dscr); } else { - /* Use slow path. */ + /* Use slow path. Adjust size for aligned accesses */ + switch (address % 4) { + case 1: + case 3: + count *= size; + size = 1; + break; + case 2: + if (size == 4) { + count *= 2; + size = 2; + } + case 0: + default: + break; + } retval = cortex_a_write_cpu_memory_slow(target, size, count, buffer, &dscr); } @@ -2136,7 +2152,8 @@ static int cortex_a_read_cpu_memory_slow(struct target *target, { /* Reads count objects of size size into *buffer. Old value of DSCR must be * in *dscr; updated to new value. This is slow because it works for - * non-word-sized objects and (maybe) unaligned accesses. If size == 4 and + * non-word-sized objects. Avoid unaligned accesses as they do not work + * on memory address space without "Normal" attribute. If size == 4 and * the address is aligned, cortex_a_read_cpu_memory_fast should be * preferred. * Preconditions: @@ -2352,7 +2369,23 @@ static int cortex_a_read_cpu_memory(struct target *target, /* We are doing a word-aligned transfer, so use fast mode. */ retval = cortex_a_read_cpu_memory_fast(target, count, buffer, &dscr); } else { - /* Use slow path. */ + /* Use slow path. Adjust size for aligned accesses */ + switch (address % 4) { + case 1: + case 3: + count *= size; + size = 1; + break; + case 2: + if (size == 4) { + count *= 2; + size = 2; + } + break; + case 0: + default: + break; + } retval = cortex_a_read_cpu_memory_slow(target, size, count, buffer, &dscr); } From c983f8ee00527504cedad932858f00458d7b9b43 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Fri, 17 May 2019 22:18:45 +0300 Subject: [PATCH 014/354] gdb-server: Create arch-specific structure type for every feature As it is mentioned here [1] type's ID is unique name within containing feature. That said if regs of the same type located in different features it's required to insert type definition at least in each feature. See more details in discussion here [2]. [1] https://sourceware.org/gdb/onlinedocs/gdb/Target-Description-Format.html#Types [2] https://github.com/foss-for-synopsys-dwc-arc-processors/openocd/commit/2a5f5125ac8fa0e1359b6be03b209f9f5d1ade82#r33460077 Change-Id: Id92b061cfbf47d5c032a02c2c406b28affd0b02a Signed-off-by: Alexey Brodkin Reviewed-on: http://openocd.zylin.com/5179 Tested-by: jenkins Reviewed-by: Muhammad Omair Javaid Reviewed-by: Matthias Welwarsky --- src/server/gdb_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 02020425e..0370fcd5b 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -2205,14 +2205,11 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o int reg_list_size; char const *architecture; char const **features = NULL; - char const **arch_defined_types = NULL; int feature_list_size = 0; - int num_arch_defined_types = 0; char *tdesc = NULL; int pos = 0; int size = 0; - arch_defined_types = calloc(1, sizeof(char *)); retval = target_get_gdb_reg_list_noread(target, ®_list, ®_list_size, REG_CLASS_ALL); @@ -2254,7 +2251,10 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o /* generate target description according to register list */ if (features != NULL) { while (features[current_feature]) { + char const **arch_defined_types = NULL; + int num_arch_defined_types = 0; + arch_defined_types = calloc(1, sizeof(char *)); xml_printf(&retval, &tdesc, &pos, &size, "\n", features[current_feature]); @@ -2319,6 +2319,7 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o "\n"); current_feature++; + free(arch_defined_types); } } @@ -2328,7 +2329,6 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o error: free(features); free(reg_list); - free(arch_defined_types); if (retval == ERROR_OK) *tdesc_out = tdesc; From a944ee28d98d538c6a46f8026bbf0f0e90219c36 Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Mon, 20 Aug 2018 15:34:19 +0200 Subject: [PATCH 015/354] gdb_server: Support vRun packet, allow setting cmdline from GDB GDB uses the vRun packet if available to restart a running process in extended remote mode. Support this like the R packet and set the semihosting command-line to allow it to be specified from GDB. Change-Id: I9cb812b22170630f782113c9927e46e0cd5b1f0f Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/5186 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Matthias Welwarsky --- src/server/gdb_server.c | 110 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 8 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 0370fcd5b..c8f0e523c 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "server.h" #include #include "gdb_server.h" @@ -2887,6 +2888,96 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p return false; } +static char *next_hex_encoded_field(const char **str, char sep) +{ + size_t hexlen; + const char *hex = *str; + if (hex[0] == '\0') + return NULL; + + const char *end = strchr(hex, sep); + if (end == NULL) + hexlen = strlen(hex); + else + hexlen = end - hex; + *str = hex + hexlen + 1; + + if (hexlen % 2 != 0) { + /* Malformed hex data */ + return NULL; + } + + size_t count = hexlen / 2; + char *decoded = malloc(count + 1); + if (decoded == NULL) + return NULL; + + size_t converted = unhexify((void *)decoded, hex, count); + if (converted != count) { + free(decoded); + return NULL; + } + + decoded[count] = '\0'; + return decoded; +} + +/* handle extended restart packet */ +static void gdb_restart_inferior(struct connection *connection, const char *packet, int packet_size) +{ + struct gdb_connection *gdb_con = connection->priv; + struct target *target = get_target_from_connection(connection); + + breakpoint_clear_target(target); + watchpoint_clear_target(target); + command_run_linef(connection->cmd_ctx, "ocd_gdb_restart %s", + target_name(target)); + /* set connection as attached after reset */ + gdb_con->attached = true; + /* info rtos parts */ + gdb_thread_packet(connection, packet, packet_size); +} + +static bool gdb_handle_vrun_packet(struct connection *connection, const char *packet, int packet_size) +{ + struct target *target = get_target_from_connection(connection); + const char *parse = packet; + + /* Skip "vRun" */ + parse += 4; + + if (parse[0] != ';') + return false; + parse++; + + /* Skip first field "filename"; don't know what to do with it. */ + free(next_hex_encoded_field(&parse, ';')); + + char *cmdline = next_hex_encoded_field(&parse, ';'); + char *arg; + while (cmdline != NULL && (arg = next_hex_encoded_field(&parse, ';')) != NULL) { + char *new_cmdline = alloc_printf("%s %s", cmdline, arg); + free(cmdline); + free(arg); + cmdline = new_cmdline; + } + + if (cmdline != NULL) { + if (target->semihosting != NULL) { + LOG_INFO("GDB set inferior command line to '%s'", cmdline); + free(target->semihosting->cmdline); + target->semihosting->cmdline = cmdline; + } else { + LOG_INFO("GDB set inferior command line to '%s' but semihosting is unavailable", cmdline); + free(cmdline); + } + } + + gdb_restart_inferior(connection, packet, packet_size); + gdb_put_packet(connection, "S00", 3); + return true; +} + static int gdb_v_packet(struct connection *connection, char const *packet, int packet_size) { @@ -2908,6 +2999,16 @@ static int gdb_v_packet(struct connection *connection, return ERROR_OK; } + if (strncmp(packet, "vRun", 4) == 0) { + bool handled; + + handled = gdb_handle_vrun_packet(connection, packet, packet_size); + if (!handled) + gdb_put_packet(connection, "", 0); + + return ERROR_OK; + } + /* if flash programming disabled - send a empty reply */ if (gdb_flash_program == 0) { @@ -3300,14 +3401,7 @@ static int gdb_input_inner(struct connection *connection) break; case 'R': /* handle extended restart packet */ - breakpoint_clear_target(target); - watchpoint_clear_target(target); - command_run_linef(connection->cmd_ctx, "ocd_gdb_restart %s", - target_name(target)); - /* set connection as attached after reset */ - gdb_con->attached = true; - /* info rtos parts */ - gdb_thread_packet(connection, packet, packet_size); + gdb_restart_inferior(connection, packet, packet_size); break; case 'j': From e99a43a27605c174c7114478e493671875124215 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 15:19:30 +0200 Subject: [PATCH 016/354] drivers/gw16012: remove useless cast on gw16012_port The variable gw16012_port is of type uint16_t. There is no need for a cast to print it. Change the format modifier to PRIx16 Change-Id: I16fe688b9d235bae46525635d07849a00fba9548 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5195 Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- src/jtag/drivers/gw16012.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c index e65f56cd1..6969e8b79 100644 --- a/src/jtag/drivers/gw16012.c +++ b/src/jtag/drivers/gw16012.c @@ -448,7 +448,7 @@ static int gw16012_init_device(void) LOG_WARNING("No gw16012 port specified, using default '0x378' (LPT1)"); } - LOG_DEBUG("requesting privileges for parallel port 0x%lx...", (long unsigned)(gw16012_port)); + LOG_DEBUG("requesting privileges for parallel port 0x%" PRIx16 "...", gw16012_port); #if PARPORT_USE_GIVEIO == 1 if (gw16012_get_giveio_access() != 0) { #else /* PARPORT_USE_GIVEIO */ From 16065e06adac25953a63bceb0fe5bf4f2c75d6ce Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 11 Jun 2019 11:55:23 -0700 Subject: [PATCH 017/354] target/cortex_a: Extract code to read/write from/to register to/from DCC In preparation for supporting the ARM MCRR and MRRC commands which will require using two 32-bit registers to read/write a 64-bit internal register, extract the common logic to read/write from/to a register to/from DCC and make that parameterized such that we can do this through not just r0. Change-Id: Iadb73f5cde8cf5961b5a18ddd198bf39d791e610 Signed-off-by: Florian Fainelli Reviewed-on: http://openocd.zylin.com/5227 Tested-by: jenkins Reviewed-by: Matthias Welwarsky --- src/target/cortex_a.c | 59 ++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 3ed2481ba..8773ea160 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -425,6 +425,27 @@ static int cortex_a_instr_write_data_dcc(struct arm_dpm *dpm, &dscr); } +static int cortex_a_instr_write_data_rt_dcc(struct arm_dpm *dpm, + uint8_t rt, uint32_t data) +{ + struct cortex_a_common *a = dpm_to_a(dpm); + uint32_t dscr = DSCR_INSTR_COMP; + int retval; + + if (rt > 15) + return ERROR_TARGET_INVALID; + + retval = cortex_a_write_dcc(a, data); + if (retval != ERROR_OK) + return retval; + + /* DCCRX to Rt, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */ + return cortex_a_exec_opcode( + a->armv7a_common.arm.target, + ARMV4_5_MRC(14, 0, rt, 0, 5, 0), + &dscr); +} + static int cortex_a_instr_write_data_r0(struct arm_dpm *dpm, uint32_t opcode, uint32_t data) { @@ -432,15 +453,7 @@ static int cortex_a_instr_write_data_r0(struct arm_dpm *dpm, uint32_t dscr = DSCR_INSTR_COMP; int retval; - retval = cortex_a_write_dcc(a, data); - if (retval != ERROR_OK) - return retval; - - /* DCCRX to R0, "MCR p14, 0, R0, c0, c5, 0", 0xEE000E15 */ - retval = cortex_a_exec_opcode( - a->armv7a_common.arm.target, - ARMV4_5_MRC(14, 0, 0, 0, 5, 0), - &dscr); + retval = cortex_a_instr_write_data_rt_dcc(dpm, 0, data); if (retval != ERROR_OK) return retval; @@ -482,6 +495,25 @@ static int cortex_a_instr_read_data_dcc(struct arm_dpm *dpm, return cortex_a_read_dcc(a, data, &dscr); } +static int cortex_a_instr_read_data_rt_dcc(struct arm_dpm *dpm, + uint8_t rt, uint32_t *data) +{ + struct cortex_a_common *a = dpm_to_a(dpm); + uint32_t dscr = DSCR_INSTR_COMP; + int retval; + + if (rt > 15) + return ERROR_TARGET_INVALID; + + retval = cortex_a_exec_opcode( + a->armv7a_common.arm.target, + ARMV4_5_MCR(14, 0, rt, 0, 5, 0), + &dscr); + if (retval != ERROR_OK) + return retval; + + return cortex_a_read_dcc(a, data, &dscr); +} static int cortex_a_instr_read_data_r0(struct arm_dpm *dpm, uint32_t opcode, uint32_t *data) @@ -499,14 +531,7 @@ static int cortex_a_instr_read_data_r0(struct arm_dpm *dpm, return retval; /* write R0 to DCC */ - retval = cortex_a_exec_opcode( - a->armv7a_common.arm.target, - ARMV4_5_MCR(14, 0, 0, 0, 5, 0), - &dscr); - if (retval != ERROR_OK) - return retval; - - return cortex_a_read_dcc(a, data, &dscr); + return cortex_a_instr_read_data_rt_dcc(dpm, 0, data); } static int cortex_a_bpwp_enable(struct arm_dpm *dpm, unsigned index_t, From 382f4f064e76734330deb63dbcd2bfa0feb08155 Mon Sep 17 00:00:00 2001 From: Mirko Vogt Date: Fri, 11 Jan 2019 14:40:55 +0100 Subject: [PATCH 018/354] nrf5: update links to compatibility matrixes for nrf5x variants Change-Id: If51aa992ccbb8c9a2e502b74827a36a62010546d Signed-off-by: Mirko Vogt Reviewed-on: http://openocd.zylin.com/4843 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/nrf5.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 78d52b877..5266f3dab 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -138,11 +138,16 @@ struct nrf5_device_spec { .flash_size_kb = (fsize), \ } -/* The known devices table below is derived from the "nRF51 Series - * Compatibility Matrix" document, which can be found by searching for - * ATTN-51 on the Nordic Semi website: +/* The known devices table below is derived from the "nRF5x series + * compatibility matrix" documents, which can be found in the "DocLib" of + * nordic: * - * http://www.nordicsemi.com/eng/content/search?SearchText=ATTN-51 + * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51422_ic_revision_overview + * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51822_ic_revision_overview + * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51824_ic_revision_overview + * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52810/latest/COMP/nrf52810/nRF52810_ic_revision_overview + * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52832/latest/COMP/nrf52832/ic_revision_overview + * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52840/latest/COMP/nrf52840/nRF52840_ic_revision_overview * * Up to date with Matrix v2.0, plus some additional HWIDs. * From ded67990255cc1e63c77832ffd6e6bef9120873d Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sat, 28 Sep 2019 18:13:37 +0200 Subject: [PATCH 019/354] libjaylink: Update to latest Git version This version adds two new USB PIDs and fixes a build issue under MSYS2. Change-Id: I753fab827783ea64e55e59d833742c9f70a28a2b Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5309 Tested-by: jenkins Reviewed-by: Spencer Oliver --- src/jtag/drivers/libjaylink | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/drivers/libjaylink b/src/jtag/drivers/libjaylink index 4959f4e18..f73ad5e66 160000 --- a/src/jtag/drivers/libjaylink +++ b/src/jtag/drivers/libjaylink @@ -1 +1 @@ -Subproject commit 4959f4e18a2bb0de21abe66bbfe403b56f599856 +Subproject commit f73ad5e667ae8b26a52b847c603fdadaabf302a6 From 4f779a88db4c03c3cf280275c383fd3f24f9fea3 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Tue, 29 Oct 2019 22:14:46 -0500 Subject: [PATCH 020/354] jtag: jtag_vpi: Add missing 'default' to switch statement If a new JTAG command is added, then GCC will complain that enumeration value not handled in switch. Make this consistent with other drivers, and add a 'default' case. Change-Id: I66d6d0db3fcae93ea246f2d4882ffff5dec14693 Signed-off-by: Alexandru Gagniuc Reviewed-on: http://openocd.zylin.com/5340 Tested-by: jenkins Reviewed-by: Jan Matyas Reviewed-by: Franck Jullien Reviewed-by: Tomas Vanek --- src/jtag/drivers/jtag_vpi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c index 1033cedb2..3e39420fb 100644 --- a/src/jtag/drivers/jtag_vpi.c +++ b/src/jtag/drivers/jtag_vpi.c @@ -384,6 +384,11 @@ static int jtag_vpi_execute_queue(void) case JTAG_SCAN: retval = jtag_vpi_scan(cmd->cmd.scan); break; + default: + LOG_ERROR("BUG: unknown JTAG command type 0x%X", + cmd->type); + retval = ERROR_FAIL; + break; } } From 433333968079c69aede528e2fb30ab71ccb1f294 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Sun, 27 Oct 2019 11:59:47 -0500 Subject: [PATCH 021/354] jtag: usb_blaster: Add missing 'default' to switch statement If a new JTAG command is added, then GCC will complain that enumeration value not handled in switch. This is the only driver not to have a default case, so add it. Change-Id: Icb838087bb7525d057a911bd256300e256da1668 Signed-off-by: Alexandru Gagniuc Reviewed-on: http://openocd.zylin.com/5333 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- src/jtag/drivers/usb_blaster/usb_blaster.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index 165ebdcd3..48534a26f 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -816,6 +816,11 @@ static int ublast_execute_queue(void) case JTAG_SCAN: ret = ublast_scan(cmd->cmd.scan); break; + default: + LOG_ERROR("BUG: unknown JTAG command type 0x%X", + cmd->type); + ret = ERROR_FAIL; + break; } } From 9de7d9c81d91a5cfc16a1476d558d92b08d7e596 Mon Sep 17 00:00:00 2001 From: Ake Rehnman Date: Sun, 27 Oct 2019 19:48:25 +0100 Subject: [PATCH 022/354] STM8 Target relicensing to GPLv2 and later Change-Id: I21126945c0475399aaf12239b8972fde5fddd845 Signed-off-by: Ake Rehnman Reviewed-on: http://openocd.zylin.com/5331 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek Reviewed-by: Tarek BOCHKATI --- .../loaders/erase_check/stm8_erase_check.s | 30 ++++++++--------- src/target/stm8.c | 32 +++++++++---------- src/target/stm8.h | 32 +++++++++---------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/contrib/loaders/erase_check/stm8_erase_check.s b/contrib/loaders/erase_check/stm8_erase_check.s index 62694006b..04cde5b1b 100644 --- a/contrib/loaders/erase_check/stm8_erase_check.s +++ b/contrib/loaders/erase_check/stm8_erase_check.s @@ -1,19 +1,19 @@ /* - Copyright (C) 2017 Ake Rehnman - ake.rehnman(at)gmail.com - - 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . +* Copyright (C) 2017 Ake Rehnman +* ake.rehnman(at)gmail.com +* +* 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 +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . */ ;; ;; erase check memory code diff --git a/src/target/stm8.c b/src/target/stm8.c index fcfc1707e..144c797de 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -1,20 +1,20 @@ /* - OpenOCD STM8 target driver - Copyright (C) 2017 Ake Rehnman - ake.rehnman(at)gmail.com - - 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . +* OpenOCD STM8 target driver +* Copyright (C) 2017 Ake Rehnman +* ake.rehnman(at)gmail.com +* +* 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 +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . */ #ifdef HAVE_CONFIG_H diff --git a/src/target/stm8.h b/src/target/stm8.h index 39fac3e32..da7f1f119 100644 --- a/src/target/stm8.h +++ b/src/target/stm8.h @@ -1,20 +1,20 @@ /* - OpenOCD STM8 target driver - Copyright (C) 2017 Ake Rehnman - ake.rehnman(at)gmail.com - - 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 - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . +* OpenOCD STM8 target driver +* Copyright (C) 2017 Ake Rehnman +* ake.rehnman(at)gmail.com +* +* 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 +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . */ #ifndef OPENOCD_TARGET_STM8_H From 6d54d905413243cc65687e30669a94037a14cbe6 Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Sat, 13 Jan 2018 21:00:47 +0100 Subject: [PATCH 023/354] CVE-2018-5704: Prevent some forms of Cross Protocol Scripting attacks OpenOCD can be targeted by a Cross Protocol Scripting attack from a web browser running malicious code, such as the following PoC: var x = new XMLHttpRequest(); x.open("POST", "http://127.0.0.1:4444", true); x.send("exec xcalc\r\n"); This mitigation should provide some protection from browser-based attacks and is based on the corresponding fix in Redis: https://github.com/antirez/redis/blob/8075572207b5aebb1385c4f233f5302544439325/src/networking.c#L1758 Change-Id: Ia96ebe19b74b5805dc228bf7364c7971a90a4581 Signed-off-by: Andreas Fritiofson Reported-by: Josef Gajdusek Reviewed-on: http://openocd.zylin.com/4335 Tested-by: jenkins Reviewed-by: Jonathan McDowell Reviewed-by: Paul Fertser --- src/server/startup.tcl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/server/startup.tcl b/src/server/startup.tcl index 64ace4079..dd1b31e41 100644 --- a/src/server/startup.tcl +++ b/src/server/startup.tcl @@ -8,3 +8,14 @@ proc ocd_gdb_restart {target_id} { # one target reset halt } + +proc prevent_cps {} { + echo "Possible SECURITY ATTACK detected." + echo "It looks like somebody is sending POST or Host: commands to OpenOCD." + echo "This is likely due to an attacker attempting to use Cross Protocol Scripting" + echo "to compromise your OpenOCD instance. Connection aborted." + exit +} + +proc POST {args} { prevent_cps } +proc Host: {args} { prevent_cps } From be365730732231e0733353834b56f405a8219f2a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 8 Oct 2019 11:17:09 +0200 Subject: [PATCH 024/354] helper: skip including sys/sysctl.h on Linux Starting from glibc 2.30, the header file sys/sysctl.h gets deprecated on Linux, after the commit 744e82963716 ("Linux: Deprecate and sysctl") https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=744e82963716 The associated NEWS reports The Linux-specific header and the sysctl function have been deprecated and will be removed from a future version of glibc. Latest automake 1.16.1 still does not handle this case. Current OpenOCD build fails with warning and requires configure with "--disable-werror" to build. Prevent including sys/sysctl.h on Linux build. Change-Id: I5310976573352a96e5aef123352f73475f0c35fe Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5317 Tested-by: jenkins Reviewed-by: Moritz Fischer Reviewed-by: Paul Fertser --- src/helper/options.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/helper/options.c b/src/helper/options.c index b60d58de8..6622ece6c 100644 --- a/src/helper/options.c +++ b/src/helper/options.c @@ -34,9 +34,12 @@ #if IS_DARWIN #include #endif +/* sys/sysctl.h is deprecated on Linux from glibc 2.30 */ +#ifndef __linux__ #ifdef HAVE_SYS_SYSCTL_H #include #endif +#endif #if IS_WIN32 && !IS_CYGWIN #include #endif From 006d8e5444a67c8f569dcbd30add975d46635e38 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sun, 23 Dec 2018 00:39:34 +0100 Subject: [PATCH 025/354] flash/nor/nrf5: remove useless page padding and UICR autoerase nRF5 flash controller can write a word at a time. Ask flash infrastructure to handle alignment and padding. Fix mixing of offset and address in nrf5_ll_flash_write() - the original code worked just because NRF5_FLASH_BASE is 0 Change-Id: Ibe8bdf899a1764cf4117b2deda1a4618eeb16697 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4819 Tested-by: jenkins --- src/flash/nor/nrf5.c | 147 +++++-------------------------------------- 1 file changed, 16 insertions(+), 131 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 5266f3dab..4addb61d4 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -89,7 +89,7 @@ enum nrf5_uicr_registers { enum nrf5_nvmc_registers { NRF5_NVMC_BASE = 0x4001E000, /* Non-Volatile Memory - * Controller Regsters */ + * Controller Registers */ #define NRF5_NVMC_REG(offset) (NRF5_NVMC_BASE + offset) @@ -114,9 +114,6 @@ struct nrf5_info { struct nrf5_bank { struct nrf5_info *chip; bool probed; - int (*write) (struct flash_bank *bank, - struct nrf5_info *chip, - const uint8_t *buffer, uint32_t offset, uint32_t count); } bank[2]; struct target *target; }; @@ -653,19 +650,17 @@ static const uint8_t nrf5_flash_write_code[] = { /* Start a low level flash write for the specified region */ -static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t offset, const uint8_t *buffer, uint32_t bytes) +static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const uint8_t *buffer, uint32_t bytes) { struct target *target = chip->target; uint32_t buffer_size = 8192; struct working_area *write_algorithm; struct working_area *source; - uint32_t address = NRF5_FLASH_BASE + offset; struct reg_param reg_params[4]; struct armv7m_algorithm armv7m_info; int retval = ERROR_OK; - - LOG_DEBUG("Writing buffer to flash offset=0x%"PRIx32" bytes=0x%"PRIx32, offset, bytes); + LOG_DEBUG("Writing buffer to flash address=0x%"PRIx32" bytes=0x%"PRIx32, address, bytes); assert(bytes % 4 == 0); /* allocate working area with flash programming code */ @@ -674,7 +669,7 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t offset, const ui LOG_WARNING("no working area available, falling back to slow memory writes"); for (; bytes > 0; bytes -= 4) { - retval = target_write_memory(chip->target, offset, 4, 1, buffer); + retval = target_write_memory(target, address, 4, 1, buffer); if (retval != ERROR_OK) return retval; @@ -682,17 +677,13 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t offset, const ui if (retval != ERROR_OK) return retval; - offset += 4; + address += 4; buffer += 4; } return ERROR_OK; } - LOG_WARNING("using fast async flash loader. This is currently supported"); - LOG_WARNING("only with ST-Link and CMSIS-DAP. If you have issues, add"); - LOG_WARNING("\"set WORKAREASIZE 0\" before sourcing nrf51.cfg/nrf52.cfg to disable it"); - retval = target_write_buffer(target, write_algorithm->address, sizeof(nrf5_flash_write_code), nrf5_flash_write_code); @@ -743,23 +734,23 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t offset, const ui return retval; } -/* Check and erase flash sectors in specified range then start a low level page write. - start/end must be sector aligned. -*/ -static int nrf5_write_pages(struct flash_bank *bank, uint32_t start, uint32_t end, const uint8_t *buffer) +static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) { - int res = ERROR_FAIL; - struct nrf5_bank *nbank = bank->driver_priv; - struct nrf5_info *chip = nbank->chip; + struct nrf5_info *chip; - assert(start % chip->code_page_size == 0); - assert(end % chip->code_page_size == 0); + int res = nrf5_get_probed_chip_if_halted(bank, &chip); + if (res != ERROR_OK) + return res; + + assert(offset % 4 == 0); + assert(count % 4 == 0); res = nrf5_nvmc_write_enable(chip); if (res != ERROR_OK) goto error; - res = nrf5_ll_flash_write(chip, start, buffer, (end - start)); + res = nrf5_ll_flash_write(chip, bank->base + offset, buffer, count); if (res != ERROR_OK) goto error; @@ -787,111 +778,6 @@ static int nrf5_erase(struct flash_bank *bank, int first, int last) return res; } -static int nrf5_code_flash_write(struct flash_bank *bank, - struct nrf5_info *chip, - const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - - int res; - /* Need to perform reads to fill any gaps we need to preserve in the first page, - before the start of buffer, or in the last page, after the end of buffer */ - uint32_t first_page = offset/chip->code_page_size; - uint32_t last_page = DIV_ROUND_UP(offset+count, chip->code_page_size); - - uint32_t first_page_offset = first_page * chip->code_page_size; - uint32_t last_page_offset = last_page * chip->code_page_size; - - LOG_DEBUG("Padding write from 0x%08"PRIx32"-0x%08"PRIx32" as 0x%08"PRIx32"-0x%08"PRIx32, - offset, offset+count, first_page_offset, last_page_offset); - - uint32_t page_cnt = last_page - first_page; - uint8_t buffer_to_flash[page_cnt*chip->code_page_size]; - - /* Fill in any space between start of first page and start of buffer */ - uint32_t pre = offset - first_page_offset; - if (pre > 0) { - res = target_read_memory(bank->target, - first_page_offset, - 1, - pre, - buffer_to_flash); - if (res != ERROR_OK) - return res; - } - - /* Fill in main contents of buffer */ - memcpy(buffer_to_flash+pre, buffer, count); - - /* Fill in any space between end of buffer and end of last page */ - uint32_t post = last_page_offset - (offset+count); - if (post > 0) { - /* Retrieve the full row contents from Flash */ - res = target_read_memory(bank->target, - offset + count, - 1, - post, - buffer_to_flash+pre+count); - if (res != ERROR_OK) - return res; - } - - return nrf5_write_pages(bank, first_page_offset, last_page_offset, buffer_to_flash); -} - -static int nrf5_uicr_flash_write(struct flash_bank *bank, - struct nrf5_info *chip, - const uint8_t *buffer, uint32_t offset, uint32_t count) -{ - int res; - uint8_t uicr[NRF5_UICR_SIZE]; - struct flash_sector *sector = &bank->sectors[0]; - - if ((offset + count) > NRF5_UICR_SIZE) - return ERROR_FAIL; - - res = target_read_memory(bank->target, - NRF5_UICR_BASE, - 1, - NRF5_UICR_SIZE, - uicr); - - if (res != ERROR_OK) - return res; - - res = nrf5_erase_page(bank, chip, sector); - if (res != ERROR_OK) - return res; - - res = nrf5_nvmc_write_enable(chip); - if (res != ERROR_OK) - return res; - - memcpy(&uicr[offset], buffer, count); - - res = nrf5_ll_flash_write(chip, NRF5_UICR_BASE, uicr, NRF5_UICR_SIZE); - if (res != ERROR_OK) { - nrf5_nvmc_read_only(chip); - return res; - } - - return nrf5_nvmc_read_only(chip); -} - - -static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) -{ - int res; - struct nrf5_bank *nbank = bank->driver_priv; - struct nrf5_info *chip; - - res = nrf5_get_probed_chip_if_halted(bank, &chip); - if (res != ERROR_OK) - return res; - - return nbank->write(bank, chip, buffer, offset, count); -} - static void nrf5_free_driver_priv(struct flash_bank *bank) { struct nrf5_bank *nbank = bank->driver_priv; @@ -932,11 +818,9 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) switch (bank->base) { case NRF5_FLASH_BASE: nbank = &chip->bank[0]; - nbank->write = nrf5_code_flash_write; break; case NRF5_UICR_BASE: nbank = &chip->bank[1]; - nbank->write = nrf5_uicr_flash_write; break; } assert(nbank != NULL); @@ -945,6 +829,7 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) nbank->chip = chip; nbank->probed = false; bank->driver_priv = nbank; + bank->write_start_alignment = bank->write_end_alignment = 4; return ERROR_OK; } From 5da746fa09dc1fbc28b4b4431035f5058a7e76a2 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sun, 13 Jan 2019 09:31:03 +0100 Subject: [PATCH 026/354] flash/nor/nrf5: detect newer devices without HWID table nrf5 flash driver detected devices by looking up the HWID in the table of known devices. Unfortunately chips are produced with many different HWIDs for each type. All nRF52 devices have FICR INFO field suitable for device identification without need of HWID lookup. Some newer nRF51 devices have FICR INFO too although undocumented. Use this information to identify the device. nrf5_info() is reworked to show just concise info. Decoding FICR and UICR registers was moved from nrf5_info() to a new command 'nrf5 info' without functional changes. The flash bank for UICR page has the same size as program flash sector. Change-Id: I900095b9ae23ee995f8e2bef8539b75d00300da5 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4848 Tested-by: jenkins --- doc/openocd.texi | 4 + src/flash/nor/nrf5.c | 267 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 221 insertions(+), 50 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 440f43454..af1684d00 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6363,6 +6363,10 @@ works only for chips that do not have factory pre-programmed region 0 code. @end deffn +@deffn Command {nrf5 info} +Decodes and shows informations from FICR and UICR registers. +@end deffn + @end deffn @deffn {Flash Driver} ocl diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 4addb61d4..426f28733 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -71,14 +71,19 @@ enum nrf5_ficr_registers { NRF5_FICR_BLE_1MBIT2 = NRF5_FICR_REG(0x0F4), NRF5_FICR_BLE_1MBIT3 = NRF5_FICR_REG(0x0F8), NRF5_FICR_BLE_1MBIT4 = NRF5_FICR_REG(0x0FC), + + /* Following registers are available on nRF52 and on nRF51 since rev 3 */ + NRF5_FICR_INFO_PART = NRF5_FICR_REG(0x100), + NRF5_FICR_INFO_VARIANT = NRF5_FICR_REG(0x104), + NRF5_FICR_INFO_PACKAGE = NRF5_FICR_REG(0x108), + NRF5_FICR_INFO_RAM = NRF5_FICR_REG(0x10C), + NRF5_FICR_INFO_FLASH = NRF5_FICR_REG(0x110), }; enum nrf5_uicr_registers { NRF5_UICR_BASE = 0x10001000, /* User Information * Configuration Regsters */ - NRF5_UICR_SIZE = 0x100, - #define NRF5_UICR_REG(offset) (NRF5_UICR_BASE + offset) NRF5_UICR_CLENR0 = NRF5_UICR_REG(0x000), @@ -107,15 +112,12 @@ enum nrf5_nvmc_config_bits { }; -struct nrf5_info { - uint32_t code_page_size; - uint32_t refcount; - - struct nrf5_bank { - struct nrf5_info *chip; - bool probed; - } bank[2]; - struct target *target; +struct nrf52_ficr_info { + uint32_t part; + uint32_t variant; + uint32_t package; + uint32_t ram; + uint32_t flash; }; struct nrf5_device_spec { @@ -126,6 +128,23 @@ struct nrf5_device_spec { unsigned int flash_size_kb; }; +struct nrf5_info { + uint32_t refcount; + + struct nrf5_bank { + struct nrf5_info *chip; + bool probed; + } bank[2]; + struct target *target; + + /* chip identification stored in nrf5_probe() for use in nrf5_info() */ + bool ficr_info_valid; + struct nrf52_ficr_info ficr_info; + const struct nrf5_device_spec *spec; + uint32_t hwid; + unsigned int flash_size_kb; +}; + #define NRF5_DEVICE_DEF(id, pt, var, bcode, fsize) \ { \ .hwid = (id), \ @@ -207,6 +226,9 @@ static const struct nrf5_device_spec nrf5_known_devices_table[] = { NRF5_DEVICE_DEF(0x007A, "51422", "CEAA", "C0", 256), NRF5_DEVICE_DEF(0x0088, "51422", "CFAC", "A0", 256), + /* The driver fully autodects nRF52 series devices by FICR INFO, + * no need for nRF52xxx HWIDs in this table */ +#if 0 /* nRF52810 Devices */ NRF5_DEVICE_DEF(0x0142, "52810", "QFAA", "B0", 192), NRF5_DEVICE_DEF(0x0143, "52810", "QCAA", "C0", 192), @@ -218,6 +240,21 @@ static const struct nrf5_device_spec nrf5_known_devices_table[] = { /* nRF52840 Devices */ NRF5_DEVICE_DEF(0x0150, "52840", "QIAA", "C0", 1024), +#endif +}; + +struct nrf5_device_package { + uint32_t package; + const char *code; +}; + +/* Newer devices have FICR INFO.PACKAGE. + * This table converts its value to two character code */ +static const struct nrf5_device_package nrf5_packages_table[] = { + { 0x2000, "QF" }, + { 0x2001, "CH" }, + { 0x2002, "CI" }, + { 0x2005, "CK" }, }; static int nrf5_bank_is_probed(struct flash_bank *bank) @@ -463,62 +500,177 @@ static int nrf5_protect(struct flash_bank *bank, int set, int first, int last) return ERROR_OK; } -static int nrf5_probe(struct flash_bank *bank) +static bool nrf5_info_variant_to_str(uint32_t variant, char *bf) +{ + h_u32_to_be((uint8_t *)bf, variant); + bf[4] = '\0'; + if (isalnum(bf[0]) && isalnum(bf[1]) && isalnum(bf[2]) && isalnum(bf[3])) + return true; + + strcpy(bf, "xxxx"); + return false; +} + +static const char *nrf5_decode_info_package(uint32_t package) +{ + for (size_t i = 0; i < ARRAY_SIZE(nrf5_packages_table); i++) { + if (nrf5_packages_table[i].package == package) + return nrf5_packages_table[i].code; + } + return "xx"; +} + +static int nrf5_info(struct flash_bank *bank, char *buf, int buf_size) { - uint32_t hwid; - int res; struct nrf5_bank *nbank = bank->driver_priv; struct nrf5_info *chip = nbank->chip; - res = target_read_u32(chip->target, NRF5_FICR_CONFIGID, &hwid); + if (chip->spec) { + snprintf(buf, buf_size, + "nRF%s-%s(build code: %s) %ukB Flash", + chip->spec->part, chip->spec->variant, chip->spec->build_code, + chip->flash_size_kb); + + } else if (chip->ficr_info_valid) { + char variant[5]; + nrf5_info_variant_to_str(chip->ficr_info.variant, variant); + snprintf(buf, buf_size, + "nRF%" PRIx32 "-%s%.2s(build code: %s) %" PRIu32 + "kB Flash, %" PRIu32 "kB RAM", + chip->ficr_info.part, + nrf5_decode_info_package(chip->ficr_info.package), + variant, &variant[2], + chip->flash_size_kb, + chip->ficr_info.ram); + + } else { + snprintf(buf, buf_size, "nRF51xxx (HWID 0x%04" PRIx16 ") %ukB Flash", + chip->hwid, chip->flash_size_kb); + } + return ERROR_OK; +} + +static int nrf5_read_ficr_info(struct nrf5_info *chip) +{ + int res; + struct target *target = chip->target; + + chip->ficr_info_valid = false; + + res = target_read_u32(target, NRF5_FICR_INFO_PART, &chip->ficr_info.part); + if (res != ERROR_OK) { + LOG_DEBUG("Couldn't read FICR INFO.PART register"); + return res; + } + + uint32_t series = chip->ficr_info.part & 0xfffff000; + if (!(series == 0x51000 || series == 0x52000)) { + LOG_DEBUG("FICR INFO likely not implemented. Invalid PART value 0x%08" + PRIx32, chip->ficr_info.part); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + /* Now we know the device has FICR INFO filled by something relevant: + * Although it is not documented, the tested nRF51 rev 3 devices + * have FICR INFO.PART, RAM and FLASH of the same format as nRF52. + * VARIANT and PACKAGE coding is unknown for a nRF51 device. + * nRF52 devices have FICR INFO documented and always filled. */ + + res = target_read_u32(target, NRF5_FICR_INFO_VARIANT, &chip->ficr_info.variant); + if (res != ERROR_OK) + return res; + + res = target_read_u32(target, NRF5_FICR_INFO_PACKAGE, &chip->ficr_info.package); + if (res != ERROR_OK) + return res; + + res = target_read_u32(target, NRF5_FICR_INFO_RAM, &chip->ficr_info.ram); + if (res != ERROR_OK) + return res; + + res = target_read_u32(target, NRF5_FICR_INFO_FLASH, &chip->ficr_info.flash); + if (res != ERROR_OK) + return res; + + chip->ficr_info_valid = true; + return ERROR_OK; +} + +static int nrf5_probe(struct flash_bank *bank) +{ + int res; + struct nrf5_bank *nbank = bank->driver_priv; + struct nrf5_info *chip = nbank->chip; + struct target *target = chip->target; + + res = target_read_u32(target, NRF5_FICR_CONFIGID, &chip->hwid); if (res != ERROR_OK) { LOG_ERROR("Couldn't read CONFIGID register"); return res; } - hwid &= 0xFFFF; /* HWID is stored in the lower two + chip->hwid &= 0xFFFF; /* HWID is stored in the lower two * bytes of the CONFIGID register */ - const struct nrf5_device_spec *spec = NULL; + chip->spec = NULL; for (size_t i = 0; i < ARRAY_SIZE(nrf5_known_devices_table); i++) { - if (hwid == nrf5_known_devices_table[i].hwid) { - spec = &nrf5_known_devices_table[i]; + if (chip->hwid == nrf5_known_devices_table[i].hwid) { + chip->spec = &nrf5_known_devices_table[i]; break; } } - if (!chip->bank[0].probed && !chip->bank[1].probed) { - if (spec) - LOG_INFO("nRF%s-%s(build code: %s) %ukB Flash", - spec->part, spec->variant, spec->build_code, - spec->flash_size_kb); - else - LOG_WARNING("Unknown device (HWID 0x%08" PRIx32 ")", hwid); + /* Don't bail out on error for the case that some old engineering + * sample has FICR INFO registers unreadable. We can proceed anyway. */ + (void)nrf5_read_ficr_info(chip); + + if (chip->spec && chip->ficr_info_valid) { + /* check if HWID table gives the same part as FICR INFO */ + if (chip->ficr_info.part != strtoul(chip->spec->part, NULL, 16)) + LOG_WARNING("HWID 0x%04" PRIx32 " mismatch: FICR INFO.PART %" + PRIx32, chip->hwid, chip->ficr_info.part); } + /* The value stored in NRF5_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */ + uint32_t flash_page_size; + res = target_read_u32(chip->target, NRF5_FICR_CODEPAGESIZE, + &flash_page_size); + if (res != ERROR_OK) { + LOG_ERROR("Couldn't read code page size"); + return res; + } + + /* Note the register name is misleading, + * NRF5_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */ + uint32_t num_sectors; + res = target_read_u32(chip->target, NRF5_FICR_CODESIZE, &num_sectors); + if (res != ERROR_OK) { + LOG_ERROR("Couldn't read code memory size"); + return res; + } + + chip->flash_size_kb = num_sectors * flash_page_size / 1024; + + if (!chip->bank[0].probed && !chip->bank[1].probed) { + char buf[80]; + nrf5_info(bank, buf, sizeof(buf)); + if (!chip->spec && !chip->ficr_info_valid) { + LOG_INFO("Unknown device: %s", buf); + } else { + LOG_INFO("%s", buf); + } + } + + if (bank->base == NRF5_FLASH_BASE) { - /* The value stored in NRF5_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */ - res = target_read_u32(chip->target, NRF5_FICR_CODEPAGESIZE, - &chip->code_page_size); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read code page size"); - return res; - } - - /* Note the register name is misleading, - * NRF5_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */ - uint32_t num_sectors; - res = target_read_u32(chip->target, NRF5_FICR_CODESIZE, &num_sectors); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read code memory size"); - return res; - } - bank->num_sectors = num_sectors; - bank->size = num_sectors * chip->code_page_size; + bank->size = num_sectors * flash_page_size; - if (spec && bank->size / 1024 != spec->flash_size_kb) + /* Sanity check */ + if (chip->spec && chip->flash_size_kb != chip->spec->flash_size_kb) LOG_WARNING("Chip's reported Flash capacity does not match expected one"); + if (chip->ficr_info_valid && chip->flash_size_kb != chip->ficr_info.flash) + LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH"); bank->sectors = calloc(bank->num_sectors, sizeof((bank->sectors)[0])); @@ -528,8 +680,8 @@ static int nrf5_probe(struct flash_bank *bank) /* Fill out the sector information: all NRF5 sectors are the same size and * there is always a fixed number of them. */ for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].size = chip->code_page_size; - bank->sectors[i].offset = i * chip->code_page_size; + bank->sectors[i].size = flash_page_size; + bank->sectors[i].offset = i * flash_page_size; /* mark as unknown */ bank->sectors[i].is_erased = -1; @@ -540,7 +692,7 @@ static int nrf5_probe(struct flash_bank *bank) chip->bank[0].probed = true; } else { - bank->size = NRF5_UICR_SIZE; + bank->size = flash_page_size; bank->num_sectors = 1; bank->sectors = calloc(bank->num_sectors, sizeof((bank->sectors)[0])); @@ -887,9 +1039,17 @@ COMMAND_HANDLER(nrf5_handle_mass_erase_command) return ERROR_OK; } -static int nrf5_info(struct flash_bank *bank, char *buf, int buf_size) +COMMAND_HANDLER(nrf5_handle_info_command) { int res; + struct flash_bank *bank = NULL; + struct target *target = get_current_target(CMD_CTX); + + res = get_flash_bank_by_addr(target, NRF5_FLASH_BASE, true, &bank); + if (res != ERROR_OK) + return res; + + assert(bank != NULL); struct nrf5_info *chip; @@ -960,7 +1120,7 @@ static int nrf5_info(struct flash_bank *bank, char *buf, int buf_size) } } - snprintf(buf, buf_size, + command_print(CMD, "\n[factory information control block]\n\n" "code page size: %"PRIu32"B\n" "code memory size: %"PRIu32"kB\n" @@ -1019,6 +1179,13 @@ static const struct command_registration nrf5_exec_command_handlers[] = { .help = "Erase all flash contents of the chip.", .usage = "", }, + { + .name = "info", + .handler = nrf5_handle_info_command, + .mode = COMMAND_EXEC, + .help = "Show FICR and UICR info.", + .usage = "", + }, COMMAND_REGISTRATION_DONE }; From b2dbaf9e1569ddc75f461b0b378f6614ecb7a45d Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sun, 20 Jan 2019 23:56:46 +0100 Subject: [PATCH 027/354] flash/nor/nrf5: implement BPROT protection check for nRF52810,832 Also refuse 'flash protect' on any nRF52. Fail protection check on nRF52840 until ACL protection is implemented. Change-Id: I84fcf117427e4894147c3ad92e2a3597566b4fcf Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4864 Tested-by: jenkins --- src/flash/nor/nrf5.c | 193 +++++++++++++++++++++++++++++++------------ 1 file changed, 139 insertions(+), 54 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 426f28733..bd4ad0078 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -103,6 +103,8 @@ enum nrf5_nvmc_registers { NRF5_NVMC_ERASEPAGE = NRF5_NVMC_REG(0x508), NRF5_NVMC_ERASEALL = NRF5_NVMC_REG(0x50C), NRF5_NVMC_ERASEUICR = NRF5_NVMC_REG(0x514), + + NRF5_BPROT_BASE = 0x40000000, }; enum nrf5_nvmc_config_bits { @@ -120,12 +122,20 @@ struct nrf52_ficr_info { uint32_t flash; }; +enum nrf5_features { + NRF5_FEATURE_SERIES_51 = 1 << 0, + NRF5_FEATURE_SERIES_52 = 1 << 1, + NRF5_FEATURE_BPROT = 1 << 2, + NRF5_FEATURE_ACL_PROT = 1 << 3, +}; + struct nrf5_device_spec { uint16_t hwid; const char *part; const char *variant; const char *build_code; unsigned int flash_size_kb; + enum nrf5_features features; }; struct nrf5_info { @@ -142,16 +152,28 @@ struct nrf5_info { struct nrf52_ficr_info ficr_info; const struct nrf5_device_spec *spec; uint32_t hwid; + enum nrf5_features features; unsigned int flash_size_kb; }; -#define NRF5_DEVICE_DEF(id, pt, var, bcode, fsize) \ +#define NRF51_DEVICE_DEF(id, pt, var, bcode, fsize) \ { \ .hwid = (id), \ .part = pt, \ .variant = var, \ .build_code = bcode, \ .flash_size_kb = (fsize), \ +.features = NRF5_FEATURE_SERIES_51, \ +} + +#define NRF5_DEVICE_DEF(id, pt, var, bcode, fsize, features) \ +{ \ +.hwid = (id), \ +.part = pt, \ +.variant = var, \ +.build_code = bcode, \ +.flash_size_kb = (fsize), \ +.features = features, \ } /* The known devices table below is derived from the "nRF5x series @@ -173,73 +195,73 @@ struct nrf5_info { */ static const struct nrf5_device_spec nrf5_known_devices_table[] = { /* nRF51822 Devices (IC rev 1). */ - NRF5_DEVICE_DEF(0x001D, "51822", "QFAA", "CA/C0", 256), - NRF5_DEVICE_DEF(0x0026, "51822", "QFAB", "AA", 128), - NRF5_DEVICE_DEF(0x0027, "51822", "QFAB", "A0", 128), - NRF5_DEVICE_DEF(0x0020, "51822", "CEAA", "BA", 256), - NRF5_DEVICE_DEF(0x002F, "51822", "CEAA", "B0", 256), + NRF51_DEVICE_DEF(0x001D, "51822", "QFAA", "CA/C0", 256), + NRF51_DEVICE_DEF(0x0026, "51822", "QFAB", "AA", 128), + NRF51_DEVICE_DEF(0x0027, "51822", "QFAB", "A0", 128), + NRF51_DEVICE_DEF(0x0020, "51822", "CEAA", "BA", 256), + NRF51_DEVICE_DEF(0x002F, "51822", "CEAA", "B0", 256), /* Some early nRF51-DK (PCA10028) & nRF51-Dongle (PCA10031) boards with built-in jlink seem to use engineering samples not listed in the nRF51 Series Compatibility Matrix V1.0. */ - NRF5_DEVICE_DEF(0x0071, "51822", "QFAC", "AB", 256), + NRF51_DEVICE_DEF(0x0071, "51822", "QFAC", "AB", 256), /* nRF51822 Devices (IC rev 2). */ - NRF5_DEVICE_DEF(0x002A, "51822", "QFAA", "FA0", 256), - NRF5_DEVICE_DEF(0x0044, "51822", "QFAA", "GC0", 256), - NRF5_DEVICE_DEF(0x003C, "51822", "QFAA", "G0", 256), - NRF5_DEVICE_DEF(0x0057, "51822", "QFAA", "G2", 256), - NRF5_DEVICE_DEF(0x0058, "51822", "QFAA", "G3", 256), - NRF5_DEVICE_DEF(0x004C, "51822", "QFAB", "B0", 128), - NRF5_DEVICE_DEF(0x0040, "51822", "CEAA", "CA0", 256), - NRF5_DEVICE_DEF(0x0047, "51822", "CEAA", "DA0", 256), - NRF5_DEVICE_DEF(0x004D, "51822", "CEAA", "D00", 256), + NRF51_DEVICE_DEF(0x002A, "51822", "QFAA", "FA0", 256), + NRF51_DEVICE_DEF(0x0044, "51822", "QFAA", "GC0", 256), + NRF51_DEVICE_DEF(0x003C, "51822", "QFAA", "G0", 256), + NRF51_DEVICE_DEF(0x0057, "51822", "QFAA", "G2", 256), + NRF51_DEVICE_DEF(0x0058, "51822", "QFAA", "G3", 256), + NRF51_DEVICE_DEF(0x004C, "51822", "QFAB", "B0", 128), + NRF51_DEVICE_DEF(0x0040, "51822", "CEAA", "CA0", 256), + NRF51_DEVICE_DEF(0x0047, "51822", "CEAA", "DA0", 256), + NRF51_DEVICE_DEF(0x004D, "51822", "CEAA", "D00", 256), /* nRF51822 Devices (IC rev 3). */ - NRF5_DEVICE_DEF(0x0072, "51822", "QFAA", "H0", 256), - NRF5_DEVICE_DEF(0x00D1, "51822", "QFAA", "H2", 256), - NRF5_DEVICE_DEF(0x007B, "51822", "QFAB", "C0", 128), - NRF5_DEVICE_DEF(0x0083, "51822", "QFAC", "A0", 256), - NRF5_DEVICE_DEF(0x0084, "51822", "QFAC", "A1", 256), - NRF5_DEVICE_DEF(0x007D, "51822", "CDAB", "A0", 128), - NRF5_DEVICE_DEF(0x0079, "51822", "CEAA", "E0", 256), - NRF5_DEVICE_DEF(0x0087, "51822", "CFAC", "A0", 256), - NRF5_DEVICE_DEF(0x008F, "51822", "QFAA", "H1", 256), + NRF51_DEVICE_DEF(0x0072, "51822", "QFAA", "H0", 256), + NRF51_DEVICE_DEF(0x00D1, "51822", "QFAA", "H2", 256), + NRF51_DEVICE_DEF(0x007B, "51822", "QFAB", "C0", 128), + NRF51_DEVICE_DEF(0x0083, "51822", "QFAC", "A0", 256), + NRF51_DEVICE_DEF(0x0084, "51822", "QFAC", "A1", 256), + NRF51_DEVICE_DEF(0x007D, "51822", "CDAB", "A0", 128), + NRF51_DEVICE_DEF(0x0079, "51822", "CEAA", "E0", 256), + NRF51_DEVICE_DEF(0x0087, "51822", "CFAC", "A0", 256), + NRF51_DEVICE_DEF(0x008F, "51822", "QFAA", "H1", 256), /* nRF51422 Devices (IC rev 1). */ - NRF5_DEVICE_DEF(0x001E, "51422", "QFAA", "CA", 256), - NRF5_DEVICE_DEF(0x0024, "51422", "QFAA", "C0", 256), - NRF5_DEVICE_DEF(0x0031, "51422", "CEAA", "A0A", 256), + NRF51_DEVICE_DEF(0x001E, "51422", "QFAA", "CA", 256), + NRF51_DEVICE_DEF(0x0024, "51422", "QFAA", "C0", 256), + NRF51_DEVICE_DEF(0x0031, "51422", "CEAA", "A0A", 256), /* nRF51422 Devices (IC rev 2). */ - NRF5_DEVICE_DEF(0x002D, "51422", "QFAA", "DAA", 256), - NRF5_DEVICE_DEF(0x002E, "51422", "QFAA", "E0", 256), - NRF5_DEVICE_DEF(0x0061, "51422", "QFAB", "A00", 128), - NRF5_DEVICE_DEF(0x0050, "51422", "CEAA", "B0", 256), + NRF51_DEVICE_DEF(0x002D, "51422", "QFAA", "DAA", 256), + NRF51_DEVICE_DEF(0x002E, "51422", "QFAA", "E0", 256), + NRF51_DEVICE_DEF(0x0061, "51422", "QFAB", "A00", 128), + NRF51_DEVICE_DEF(0x0050, "51422", "CEAA", "B0", 256), /* nRF51422 Devices (IC rev 3). */ - NRF5_DEVICE_DEF(0x0073, "51422", "QFAA", "F0", 256), - NRF5_DEVICE_DEF(0x007C, "51422", "QFAB", "B0", 128), - NRF5_DEVICE_DEF(0x0085, "51422", "QFAC", "A0", 256), - NRF5_DEVICE_DEF(0x0086, "51422", "QFAC", "A1", 256), - NRF5_DEVICE_DEF(0x007E, "51422", "CDAB", "A0", 128), - NRF5_DEVICE_DEF(0x007A, "51422", "CEAA", "C0", 256), - NRF5_DEVICE_DEF(0x0088, "51422", "CFAC", "A0", 256), + NRF51_DEVICE_DEF(0x0073, "51422", "QFAA", "F0", 256), + NRF51_DEVICE_DEF(0x007C, "51422", "QFAB", "B0", 128), + NRF51_DEVICE_DEF(0x0085, "51422", "QFAC", "A0", 256), + NRF51_DEVICE_DEF(0x0086, "51422", "QFAC", "A1", 256), + NRF51_DEVICE_DEF(0x007E, "51422", "CDAB", "A0", 128), + NRF51_DEVICE_DEF(0x007A, "51422", "CEAA", "C0", 256), + NRF51_DEVICE_DEF(0x0088, "51422", "CFAC", "A0", 256), /* The driver fully autodects nRF52 series devices by FICR INFO, * no need for nRF52xxx HWIDs in this table */ #if 0 /* nRF52810 Devices */ - NRF5_DEVICE_DEF(0x0142, "52810", "QFAA", "B0", 192), - NRF5_DEVICE_DEF(0x0143, "52810", "QCAA", "C0", 192), + NRF5_DEVICE_DEF(0x0142, "52810", "QFAA", "B0", 192, NRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT), + NRF5_DEVICE_DEF(0x0143, "52810", "QCAA", "C0", 192, NRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT), /* nRF52832 Devices */ - NRF5_DEVICE_DEF(0x00C7, "52832", "QFAA", "B0", 512), - NRF5_DEVICE_DEF(0x0139, "52832", "QFAA", "E0", 512), - NRF5_DEVICE_DEF(0x00E3, "52832", "CIAA", "B0", 512), + NRF5_DEVICE_DEF(0x00C7, "52832", "QFAA", "B0", 512, NRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT), + NRF5_DEVICE_DEF(0x0139, "52832", "QFAA", "E0", 512, NRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT), + NRF5_DEVICE_DEF(0x00E3, "52832", "CIAA", "B0", 512, NRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT), /* nRF52840 Devices */ - NRF5_DEVICE_DEF(0x0150, "52840", "QIAA", "C0", 1024), + NRF5_DEVICE_DEF(0x0150, "52840", "QIAA", "C0", 1024, NRF5_FEATURE_SERIES_52 | NRF5_FEATURE_ACL_PROT), #endif }; @@ -408,6 +430,33 @@ error: return ERROR_FAIL; } +static int nrf5_protect_check_bprot(struct flash_bank *bank) +{ + struct nrf5_bank *nbank = bank->driver_priv; + struct nrf5_info *chip = nbank->chip; + + assert(chip != NULL); + + static uint32_t nrf5_bprot_offsets[4] = { 0x600, 0x604, 0x610, 0x614 }; + uint32_t bprot_reg = 0; + int res; + + for (int i = 0; i < bank->num_sectors; i++) { + unsigned int bit = i % 32; + if (bit == 0) { + unsigned int n_reg = i / 32; + if (n_reg >= ARRAY_SIZE(nrf5_bprot_offsets)) + break; + + res = target_read_u32(chip->target, NRF5_BPROT_BASE + nrf5_bprot_offsets[n_reg], &bprot_reg); + if (res != ERROR_OK) + return res; + } + bank->sectors[i].is_protected = (bprot_reg & (1 << bit)) ? 1 : 0; + } + return ERROR_OK; +} + static int nrf5_protect_check(struct flash_bank *bank) { int res; @@ -422,6 +471,14 @@ static int nrf5_protect_check(struct flash_bank *bank) assert(chip != NULL); + if (chip->features & NRF5_FEATURE_BPROT) + return nrf5_protect_check_bprot(bank); + + if (!(chip->features & NRF5_FEATURE_SERIES_51)) { + LOG_WARNING("Flash protection of this nRF device is not supported"); + return ERROR_FLASH_OPER_UNSUPPORTED; + } + res = target_read_u32(chip->target, NRF5_FICR_CLENR0, &clenr0); if (res != ERROR_OK) { @@ -459,6 +516,11 @@ static int nrf5_protect(struct flash_bank *bank, int set, int first, int last) if (res != ERROR_OK) return res; + if (!(chip->features & NRF5_FEATURE_SERIES_51)) { + LOG_ERROR("Flash protection setting of this nRF device is not supported"); + return ERROR_FLASH_OPER_UNSUPPORTED; + } + if (first != 0) { LOG_ERROR("Code region 0 must start at the begining of the bank"); return ERROR_FAIL; @@ -564,7 +626,27 @@ static int nrf5_read_ficr_info(struct nrf5_info *chip) } uint32_t series = chip->ficr_info.part & 0xfffff000; - if (!(series == 0x51000 || series == 0x52000)) { + switch (series) { + case 0x51000: + chip->features = NRF5_FEATURE_SERIES_51; + break; + + case 0x52000: + chip->features = NRF5_FEATURE_SERIES_52; + + switch (chip->ficr_info.part) { + case 0x52810: + case 0x52832: + chip->features |= NRF5_FEATURE_BPROT; + break; + + case 0x52840: + chip->features |= NRF5_FEATURE_ACL_PROT; + break; + } + break; + + default: LOG_DEBUG("FICR INFO likely not implemented. Invalid PART value 0x%08" PRIx32, chip->ficr_info.part); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; @@ -612,18 +694,22 @@ static int nrf5_probe(struct flash_bank *bank) chip->hwid &= 0xFFFF; /* HWID is stored in the lower two * bytes of the CONFIGID register */ - chip->spec = NULL; - for (size_t i = 0; i < ARRAY_SIZE(nrf5_known_devices_table); i++) { - if (chip->hwid == nrf5_known_devices_table[i].hwid) { - chip->spec = &nrf5_known_devices_table[i]; - break; - } - } + /* guess a nRF51 series if the device has no FICR INFO and we don't know HWID */ + chip->features = NRF5_FEATURE_SERIES_51; /* Don't bail out on error for the case that some old engineering * sample has FICR INFO registers unreadable. We can proceed anyway. */ (void)nrf5_read_ficr_info(chip); + chip->spec = NULL; + for (size_t i = 0; i < ARRAY_SIZE(nrf5_known_devices_table); i++) { + if (chip->hwid == nrf5_known_devices_table[i].hwid) { + chip->spec = &nrf5_known_devices_table[i]; + chip->features = chip->spec->features; + break; + } + } + if (chip->spec && chip->ficr_info_valid) { /* check if HWID table gives the same part as FICR INFO */ if (chip->ficr_info.part != strtoul(chip->spec->part, NULL, 16)) @@ -661,7 +747,6 @@ static int nrf5_probe(struct flash_bank *bank) } } - if (bank->base == NRF5_FLASH_BASE) { bank->num_sectors = num_sectors; bank->size = num_sectors * flash_page_size; From e3fb76374c92264e5d684c3809b52fb2047e627b Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sun, 20 Jan 2019 23:58:51 +0100 Subject: [PATCH 028/354] flash/nor/nrf5: refactor sector allocation to use alloc_block_array() Change-Id: Ied8ea917cec492fc6bb8836a92d8c4ceaf3b499b Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4865 Tested-by: jenkins --- src/flash/nor/nrf5.c | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index bd4ad0078..f0ae20367 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -748,46 +748,31 @@ static int nrf5_probe(struct flash_bank *bank) } if (bank->base == NRF5_FLASH_BASE) { - bank->num_sectors = num_sectors; - bank->size = num_sectors * flash_page_size; - /* Sanity check */ if (chip->spec && chip->flash_size_kb != chip->spec->flash_size_kb) LOG_WARNING("Chip's reported Flash capacity does not match expected one"); if (chip->ficr_info_valid && chip->flash_size_kb != chip->ficr_info.flash) LOG_WARNING("Chip's reported Flash capacity does not match FICR INFO.FLASH"); - bank->sectors = calloc(bank->num_sectors, - sizeof((bank->sectors)[0])); + bank->num_sectors = num_sectors; + bank->size = num_sectors * flash_page_size; + + bank->sectors = alloc_block_array(0, flash_page_size, num_sectors); if (!bank->sectors) - return ERROR_FLASH_BANK_NOT_PROBED; - - /* Fill out the sector information: all NRF5 sectors are the same size and - * there is always a fixed number of them. */ - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].size = flash_page_size; - bank->sectors[i].offset = i * flash_page_size; - - /* mark as unknown */ - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = -1; - } + return ERROR_FAIL; nrf5_protect_check(bank); chip->bank[0].probed = true; + } else { - bank->size = flash_page_size; bank->num_sectors = 1; - bank->sectors = calloc(bank->num_sectors, - sizeof((bank->sectors)[0])); + bank->size = flash_page_size; + + bank->sectors = alloc_block_array(0, flash_page_size, num_sectors); if (!bank->sectors) - return ERROR_FLASH_BANK_NOT_PROBED; + return ERROR_FAIL; - bank->sectors[0].size = bank->size; - bank->sectors[0].offset = 0; - - bank->sectors[0].is_erased = 0; bank->sectors[0].is_protected = 0; chip->bank[1].probed = true; From 882df85ec1d59e9c0ed82bfc44d0132dea647f87 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 21 Jan 2019 14:43:21 +0100 Subject: [PATCH 029/354] flash/nor/nrf5: rename registers by nRF series Change-Id: I70af671c52665b27a28508e06e7d3e5e40a621f7 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4866 Tested-by: jenkins --- src/flash/nor/nrf5.c | 105 ++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index f0ae20367..db54ddb6f 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -39,13 +39,15 @@ enum nrf5_ficr_registers { NRF5_FICR_CODEPAGESIZE = NRF5_FICR_REG(0x010), NRF5_FICR_CODESIZE = NRF5_FICR_REG(0x014), - NRF5_FICR_CLENR0 = NRF5_FICR_REG(0x028), - NRF5_FICR_PPFC = NRF5_FICR_REG(0x02C), - NRF5_FICR_NUMRAMBLOCK = NRF5_FICR_REG(0x034), - NRF5_FICR_SIZERAMBLOCK0 = NRF5_FICR_REG(0x038), - NRF5_FICR_SIZERAMBLOCK1 = NRF5_FICR_REG(0x03C), - NRF5_FICR_SIZERAMBLOCK2 = NRF5_FICR_REG(0x040), - NRF5_FICR_SIZERAMBLOCK3 = NRF5_FICR_REG(0x044), + + NRF51_FICR_CLENR0 = NRF5_FICR_REG(0x028), + NRF51_FICR_PPFC = NRF5_FICR_REG(0x02C), + NRF51_FICR_NUMRAMBLOCK = NRF5_FICR_REG(0x034), + NRF51_FICR_SIZERAMBLOCK0 = NRF5_FICR_REG(0x038), + NRF51_FICR_SIZERAMBLOCK1 = NRF5_FICR_REG(0x03C), + NRF51_FICR_SIZERAMBLOCK2 = NRF5_FICR_REG(0x040), + NRF51_FICR_SIZERAMBLOCK3 = NRF5_FICR_REG(0x044), + NRF5_FICR_CONFIGID = NRF5_FICR_REG(0x05C), NRF5_FICR_DEVICEID0 = NRF5_FICR_REG(0x060), NRF5_FICR_DEVICEID1 = NRF5_FICR_REG(0x064), @@ -60,17 +62,18 @@ enum nrf5_ficr_registers { NRF5_FICR_DEVICEADDRTYPE = NRF5_FICR_REG(0x0A0), NRF5_FICR_DEVICEADDR0 = NRF5_FICR_REG(0x0A4), NRF5_FICR_DEVICEADDR1 = NRF5_FICR_REG(0x0A8), - NRF5_FICR_OVERRIDEN = NRF5_FICR_REG(0x0AC), - NRF5_FICR_NRF_1MBIT0 = NRF5_FICR_REG(0x0B0), - NRF5_FICR_NRF_1MBIT1 = NRF5_FICR_REG(0x0B4), - NRF5_FICR_NRF_1MBIT2 = NRF5_FICR_REG(0x0B8), - NRF5_FICR_NRF_1MBIT3 = NRF5_FICR_REG(0x0BC), - NRF5_FICR_NRF_1MBIT4 = NRF5_FICR_REG(0x0C0), - NRF5_FICR_BLE_1MBIT0 = NRF5_FICR_REG(0x0EC), - NRF5_FICR_BLE_1MBIT1 = NRF5_FICR_REG(0x0F0), - NRF5_FICR_BLE_1MBIT2 = NRF5_FICR_REG(0x0F4), - NRF5_FICR_BLE_1MBIT3 = NRF5_FICR_REG(0x0F8), - NRF5_FICR_BLE_1MBIT4 = NRF5_FICR_REG(0x0FC), + + NRF51_FICR_OVERRIDEN = NRF5_FICR_REG(0x0AC), + NRF51_FICR_NRF_1MBIT0 = NRF5_FICR_REG(0x0B0), + NRF51_FICR_NRF_1MBIT1 = NRF5_FICR_REG(0x0B4), + NRF51_FICR_NRF_1MBIT2 = NRF5_FICR_REG(0x0B8), + NRF51_FICR_NRF_1MBIT3 = NRF5_FICR_REG(0x0BC), + NRF51_FICR_NRF_1MBIT4 = NRF5_FICR_REG(0x0C0), + NRF51_FICR_BLE_1MBIT0 = NRF5_FICR_REG(0x0EC), + NRF51_FICR_BLE_1MBIT1 = NRF5_FICR_REG(0x0F0), + NRF51_FICR_BLE_1MBIT2 = NRF5_FICR_REG(0x0F4), + NRF51_FICR_BLE_1MBIT3 = NRF5_FICR_REG(0x0F8), + NRF51_FICR_BLE_1MBIT4 = NRF5_FICR_REG(0x0FC), /* Following registers are available on nRF52 and on nRF51 since rev 3 */ NRF5_FICR_INFO_PART = NRF5_FICR_REG(0x100), @@ -86,10 +89,10 @@ enum nrf5_uicr_registers { #define NRF5_UICR_REG(offset) (NRF5_UICR_BASE + offset) - NRF5_UICR_CLENR0 = NRF5_UICR_REG(0x000), - NRF5_UICR_RBPCONF = NRF5_UICR_REG(0x004), - NRF5_UICR_XTALFREQ = NRF5_UICR_REG(0x008), - NRF5_UICR_FWID = NRF5_UICR_REG(0x010), + NRF51_UICR_CLENR0 = NRF5_UICR_REG(0x000), + NRF51_UICR_RBPCONF = NRF5_UICR_REG(0x004), + NRF51_UICR_XTALFREQ = NRF5_UICR_REG(0x008), + NRF51_UICR_FWID = NRF5_UICR_REG(0x010), }; enum nrf5_nvmc_registers { @@ -479,7 +482,7 @@ static int nrf5_protect_check(struct flash_bank *bank) return ERROR_FLASH_OPER_UNSUPPORTED; } - res = target_read_u32(chip->target, NRF5_FICR_CLENR0, + res = target_read_u32(chip->target, NRF51_FICR_CLENR0, &clenr0); if (res != ERROR_OK) { LOG_ERROR("Couldn't read code region 0 size[FICR]"); @@ -487,7 +490,7 @@ static int nrf5_protect_check(struct flash_bank *bank) } if (clenr0 == 0xFFFFFFFF) { - res = target_read_u32(chip->target, NRF5_UICR_CLENR0, + res = target_read_u32(chip->target, NRF51_UICR_CLENR0, &clenr0); if (res != ERROR_OK) { LOG_ERROR("Couldn't read code region 0 size[UICR]"); @@ -526,7 +529,7 @@ static int nrf5_protect(struct flash_bank *bank, int set, int first, int last) return ERROR_FAIL; } - res = target_read_u32(chip->target, NRF5_FICR_PPFC, + res = target_read_u32(chip->target, NRF51_FICR_PPFC, &ppfc); if (res != ERROR_OK) { LOG_ERROR("Couldn't read PPFC register"); @@ -538,7 +541,7 @@ static int nrf5_protect(struct flash_bank *bank, int set, int first, int last) return ERROR_FAIL; } - res = target_read_u32(chip->target, NRF5_UICR_CLENR0, + res = target_read_u32(chip->target, NRF51_UICR_CLENR0, &clenr0); if (res != ERROR_OK) { LOG_ERROR("Couldn't read code region 0 size[UICR]"); @@ -546,7 +549,7 @@ static int nrf5_protect(struct flash_bank *bank, int set, int first, int last) } if (clenr0 == 0xFFFFFFFF) { - res = target_write_u32(chip->target, NRF5_UICR_CLENR0, + res = target_write_u32(chip->target, NRF51_UICR_CLENR0, clenr0); if (res != ERROR_OK) { LOG_ERROR("Couldn't write code region 0 size[UICR]"); @@ -815,7 +818,7 @@ static int nrf5_erase_page(struct flash_bank *bank, if (bank->base == NRF5_UICR_BASE) { uint32_t ppfc; - res = target_read_u32(chip->target, NRF5_FICR_PPFC, + res = target_read_u32(chip->target, NRF51_FICR_PPFC, &ppfc); if (res != ERROR_OK) { LOG_ERROR("Couldn't read PPFC register"); @@ -1076,7 +1079,7 @@ COMMAND_HANDLER(nrf5_handle_mass_erase_command) uint32_t ppfc; - res = target_read_u32(target, NRF5_FICR_PPFC, + res = target_read_u32(target, NRF51_FICR_PPFC, &ppfc); if (res != ERROR_OK) { LOG_ERROR("Couldn't read PPFC register"); @@ -1133,13 +1136,13 @@ COMMAND_HANDLER(nrf5_handle_info_command) } ficr[] = { { .address = NRF5_FICR_CODEPAGESIZE }, { .address = NRF5_FICR_CODESIZE }, - { .address = NRF5_FICR_CLENR0 }, - { .address = NRF5_FICR_PPFC }, - { .address = NRF5_FICR_NUMRAMBLOCK }, - { .address = NRF5_FICR_SIZERAMBLOCK0 }, - { .address = NRF5_FICR_SIZERAMBLOCK1 }, - { .address = NRF5_FICR_SIZERAMBLOCK2 }, - { .address = NRF5_FICR_SIZERAMBLOCK3 }, + { .address = NRF51_FICR_CLENR0 }, + { .address = NRF51_FICR_PPFC }, + { .address = NRF51_FICR_NUMRAMBLOCK }, + { .address = NRF51_FICR_SIZERAMBLOCK0 }, + { .address = NRF51_FICR_SIZERAMBLOCK1 }, + { .address = NRF51_FICR_SIZERAMBLOCK2 }, + { .address = NRF51_FICR_SIZERAMBLOCK3 }, { .address = NRF5_FICR_CONFIGID }, { .address = NRF5_FICR_DEVICEID0 }, { .address = NRF5_FICR_DEVICEID1 }, @@ -1154,22 +1157,22 @@ COMMAND_HANDLER(nrf5_handle_info_command) { .address = NRF5_FICR_DEVICEADDRTYPE }, { .address = NRF5_FICR_DEVICEADDR0 }, { .address = NRF5_FICR_DEVICEADDR1 }, - { .address = NRF5_FICR_OVERRIDEN }, - { .address = NRF5_FICR_NRF_1MBIT0 }, - { .address = NRF5_FICR_NRF_1MBIT1 }, - { .address = NRF5_FICR_NRF_1MBIT2 }, - { .address = NRF5_FICR_NRF_1MBIT3 }, - { .address = NRF5_FICR_NRF_1MBIT4 }, - { .address = NRF5_FICR_BLE_1MBIT0 }, - { .address = NRF5_FICR_BLE_1MBIT1 }, - { .address = NRF5_FICR_BLE_1MBIT2 }, - { .address = NRF5_FICR_BLE_1MBIT3 }, - { .address = NRF5_FICR_BLE_1MBIT4 }, + { .address = NRF51_FICR_OVERRIDEN }, + { .address = NRF51_FICR_NRF_1MBIT0 }, + { .address = NRF51_FICR_NRF_1MBIT1 }, + { .address = NRF51_FICR_NRF_1MBIT2 }, + { .address = NRF51_FICR_NRF_1MBIT3 }, + { .address = NRF51_FICR_NRF_1MBIT4 }, + { .address = NRF51_FICR_BLE_1MBIT0 }, + { .address = NRF51_FICR_BLE_1MBIT1 }, + { .address = NRF51_FICR_BLE_1MBIT2 }, + { .address = NRF51_FICR_BLE_1MBIT3 }, + { .address = NRF51_FICR_BLE_1MBIT4 }, }, uicr[] = { - { .address = NRF5_UICR_CLENR0, }, - { .address = NRF5_UICR_RBPCONF }, - { .address = NRF5_UICR_XTALFREQ }, - { .address = NRF5_UICR_FWID }, + { .address = NRF51_UICR_CLENR0, }, + { .address = NRF51_UICR_RBPCONF }, + { .address = NRF51_UICR_XTALFREQ }, + { .address = NRF51_UICR_FWID }, }; for (size_t i = 0; i < ARRAY_SIZE(ficr); i++) { From e2ca8914f2587dd9a807dc88339cc5f02707bd01 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 21 Jan 2019 14:44:45 +0100 Subject: [PATCH 030/354] flash/nor/nrf5: do not check FICR PPFC on nRF52 Change-Id: I6beee9b85a542040f2495513b5ba51bd8e1389db Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4867 Tested-by: jenkins --- src/flash/nor/nrf5.c | 53 +++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index db54ddb6f..c19c4eabb 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -817,23 +817,25 @@ static int nrf5_erase_page(struct flash_bank *bank, } if (bank->base == NRF5_UICR_BASE) { - uint32_t ppfc; - res = target_read_u32(chip->target, NRF51_FICR_PPFC, + if (chip->features & NRF5_FEATURE_SERIES_51) { + uint32_t ppfc; + res = target_read_u32(chip->target, NRF51_FICR_PPFC, &ppfc); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read PPFC register"); - return res; - } + if (res != ERROR_OK) { + LOG_ERROR("Couldn't read PPFC register"); + return res; + } - if ((ppfc & 0xFF) == 0xFF) { - /* We can't erase the UICR. Double-check to - see if it's already erased before complaining. */ - default_flash_blank_check(bank); - if (sector->is_erased == 1) - return ERROR_OK; + if ((ppfc & 0xFF) == 0xFF) { + /* We can't erase the UICR. Double-check to + see if it's already erased before complaining. */ + default_flash_blank_check(bank); + if (sector->is_erased == 1) + return ERROR_OK; - LOG_ERROR("The chip was not pre-programmed with SoftDevice stack and UICR cannot be erased separately. Please issue mass erase before trying to write to this region"); - return ERROR_FAIL; + LOG_ERROR("The chip was not pre-programmed with SoftDevice stack and UICR cannot be erased separately. Please issue mass erase before trying to write to this region"); + return ERROR_FAIL; + } } res = nrf5_nvmc_generic_erase(chip, @@ -1077,19 +1079,20 @@ COMMAND_HANDLER(nrf5_handle_mass_erase_command) if (res != ERROR_OK) return res; - uint32_t ppfc; - - res = target_read_u32(target, NRF51_FICR_PPFC, + if (chip->features & NRF5_FEATURE_SERIES_51) { + uint32_t ppfc; + res = target_read_u32(target, NRF51_FICR_PPFC, &ppfc); - if (res != ERROR_OK) { - LOG_ERROR("Couldn't read PPFC register"); - return res; - } + if (res != ERROR_OK) { + LOG_ERROR("Couldn't read PPFC register"); + return res; + } - if ((ppfc & 0xFF) == 0x00) { - LOG_ERROR("Code region 0 size was pre-programmed at the factory, " - "mass erase command won't work."); - return ERROR_FAIL; + if ((ppfc & 0xFF) == 0x00) { + LOG_ERROR("Code region 0 size was pre-programmed at the factory, " + "mass erase command won't work."); + return ERROR_FAIL; + } } res = nrf5_erase_all(chip); From d8288a22c14ac5cc00d4255c3225cdfd4ad38fbb Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 21 Jan 2019 16:25:07 +0100 Subject: [PATCH 031/354] flash/nor/nrf5: show RAM size on old nRF51 devices (rev 1, 2) Change-Id: I2452c084b9bd9e401bd49e15791428a53df1cd1d Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4868 Tested-by: jenkins --- src/flash/nor/nrf5.c | 68 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index c19c4eabb..dac08bd4a 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -157,6 +157,7 @@ struct nrf5_info { uint32_t hwid; enum nrf5_features features; unsigned int flash_size_kb; + unsigned int ram_size_kb; }; #define NRF51_DEVICE_DEF(id, pt, var, bcode, fsize) \ @@ -589,29 +590,31 @@ static int nrf5_info(struct flash_bank *bank, char *buf, int buf_size) { struct nrf5_bank *nbank = bank->driver_priv; struct nrf5_info *chip = nbank->chip; + int res; if (chip->spec) { - snprintf(buf, buf_size, - "nRF%s-%s(build code: %s) %ukB Flash", - chip->spec->part, chip->spec->variant, chip->spec->build_code, - chip->flash_size_kb); + res = snprintf(buf, buf_size, + "nRF%s-%s(build code: %s)", + chip->spec->part, chip->spec->variant, chip->spec->build_code); } else if (chip->ficr_info_valid) { char variant[5]; nrf5_info_variant_to_str(chip->ficr_info.variant, variant); - snprintf(buf, buf_size, - "nRF%" PRIx32 "-%s%.2s(build code: %s) %" PRIu32 - "kB Flash, %" PRIu32 "kB RAM", + res = snprintf(buf, buf_size, + "nRF%" PRIx32 "-%s%.2s(build code: %s)", chip->ficr_info.part, nrf5_decode_info_package(chip->ficr_info.package), - variant, &variant[2], - chip->flash_size_kb, - chip->ficr_info.ram); + variant, &variant[2]); } else { - snprintf(buf, buf_size, "nRF51xxx (HWID 0x%04" PRIx16 ") %ukB Flash", - chip->hwid, chip->flash_size_kb); + res = snprintf(buf, buf_size, "nRF51xxx (HWID 0x%04" PRIx16 ")", + chip->hwid); } + if (res <= 0) + return ERROR_FAIL; + + snprintf(buf + res, buf_size - res, " %ukB Flash, %ukB RAM", + chip->flash_size_kb, chip->ram_size_kb); return ERROR_OK; } @@ -681,6 +684,39 @@ static int nrf5_read_ficr_info(struct nrf5_info *chip) return ERROR_OK; } +static int nrf5_get_ram_size(struct target *target, uint32_t *ram_size) +{ + int res; + + *ram_size = 0; + + uint32_t numramblock; + res = target_read_u32(target, NRF51_FICR_NUMRAMBLOCK, &numramblock); + if (res != ERROR_OK) { + LOG_DEBUG("Couldn't read FICR NUMRAMBLOCK register"); + return res; + } + + if (numramblock < 1 || numramblock > 4) { + LOG_DEBUG("FICR NUMRAMBLOCK strange value %" PRIx32, numramblock); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + for (unsigned int i = 0; i < numramblock; i++) { + uint32_t sizeramblock; + res = target_read_u32(target, NRF51_FICR_SIZERAMBLOCK0 + sizeof(uint32_t)*i, &sizeramblock); + if (res != ERROR_OK) { + LOG_DEBUG("Couldn't read FICR NUMRAMBLOCK register"); + return res; + } + if (sizeramblock < 1024 || sizeramblock > 65536) + LOG_DEBUG("FICR SIZERAMBLOCK strange value %" PRIx32, sizeramblock); + else + *ram_size += sizeramblock; + } + return res; +} + static int nrf5_probe(struct flash_bank *bank) { int res; @@ -720,6 +756,14 @@ static int nrf5_probe(struct flash_bank *bank) PRIx32, chip->hwid, chip->ficr_info.part); } + if (chip->ficr_info_valid) { + chip->ram_size_kb = chip->ficr_info.ram; + } else { + uint32_t ram_size; + nrf5_get_ram_size(target, &ram_size); + chip->ram_size_kb = ram_size / 1024; + } + /* The value stored in NRF5_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */ uint32_t flash_page_size; res = target_read_u32(chip->target, NRF5_FICR_CODEPAGESIZE, From 21bc29d1d66d3860e1343248864b9fa9f4b87280 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Wed, 23 Jan 2019 20:36:46 +0100 Subject: [PATCH 032/354] flash/nor/nrf5: fix allocation of driver_priv and sector array Drop static pointer to allocated struct nrf5_info, iterate over the flash bank list to find previously allocated nrf5 instances. nrf5 is swd only device, so static allocation makes no harm, but we should avoid copying the wrong code to other flash drivers. Free sector array before allocating it to avoid memory leak on re-probing device. Change-Id: I781d8f4418a91c043f2393e5ecc5278fc6df3566 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4910 Tested-by: jenkins --- src/flash/nor/nrf5.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index dac08bd4a..c1fd257ef 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -283,6 +283,8 @@ static const struct nrf5_device_package nrf5_packages_table[] = { { 0x2005, "CK" }, }; +const struct flash_driver nrf5_flash, nrf51_flash; + static int nrf5_bank_is_probed(struct flash_bank *bank) { struct nrf5_bank *nbank = bank->driver_priv; @@ -794,6 +796,8 @@ static int nrf5_probe(struct flash_bank *bank) } } + free(bank->sectors); + if (bank->base == NRF5_FLASH_BASE) { /* Sanity check */ if (chip->spec && chip->flash_size_kb != chip->spec->flash_size_kb) @@ -1063,9 +1067,31 @@ static void nrf5_free_driver_priv(struct flash_bank *bank) } } +static struct nrf5_info *nrf5_get_chip(struct target *target) +{ + struct flash_bank *bank_iter; + + /* iterate over nrf5 banks of same target */ + for (bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) { + if (bank_iter->driver != &nrf5_flash && bank_iter->driver != &nrf51_flash) + continue; + + if (bank_iter->target != target) + continue; + + struct nrf5_bank *nbank = bank_iter->driver_priv; + if (!nbank) + continue; + + if (nbank->chip) + return nbank->chip; + } + return NULL; +} + FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) { - static struct nrf5_info *chip; + struct nrf5_info *chip; struct nrf5_bank *nbank = NULL; switch (bank->base) { @@ -1077,6 +1103,7 @@ FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command) return ERROR_FAIL; } + chip = nrf5_get_chip(bank->target); if (!chip) { /* Create a new chip */ chip = calloc(1, sizeof(*chip)); From 1b276c0ad56ed7d1ef72787b6bee885ac5d063a8 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Thu, 29 Aug 2019 17:03:19 +0200 Subject: [PATCH 033/354] flash/nor/stm32h7x: remove stm32x_options.protection2 Each bank had to store its options only, there is no need for bank1 to sneak into bank2 options. Furthermore, some variants do not have a second bank. Change-Id: I9229eb8ab4b5860ba2b0c5dbe626a54a84bca4d6 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5290 Tested-by: jenkins Reviewed-by: Christopher Head Reviewed-by: Tomas Vanek --- src/flash/nor/stm32h7x.c | 58 +++++++++------------------------------- 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index fd6bf9a09..1d128f3be 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -102,8 +102,7 @@ struct stm32h7x_rev { struct stm32x_options { uint8_t RDP; - uint32_t protection; /* bank1 WRP */ - uint32_t protection2; /* bank2 WRP */ + uint32_t protection; /* bank sectors's write protection (WPSN register) */ uint8_t user_options; uint8_t user2_options; uint8_t user3_options; @@ -307,11 +306,9 @@ static int stm32x_lock_reg(struct flash_bank *bank) static int stm32x_read_options(struct flash_bank *bank) { uint32_t optiondata; - struct stm32h7x_flash_bank *stm32x_info = NULL; + struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; struct target *target = bank->target; - stm32x_info = bank->driver_priv; - /* read current option bytes */ int retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTSR_CUR, &optiondata); if (retval != ERROR_OK) @@ -327,28 +324,20 @@ static int stm32x_read_options(struct flash_bank *bank) LOG_INFO("Device Security Bit Set"); /* read current WPSN option bytes */ - retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_WPSN_CUR, &optiondata); + retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_WPSN_CUR), &optiondata); if (retval != ERROR_OK) return retval; stm32x_info->option_bytes.protection = optiondata & 0xff; - /* read current WPSN2 option bytes */ - retval = target_read_u32(target, FLASH_REG_BASE_B1 + FLASH_WPSN_CUR, &optiondata); - if (retval != ERROR_OK) - return retval; - stm32x_info->option_bytes.protection2 = optiondata & 0xff; - return ERROR_OK; } static int stm32x_write_options(struct flash_bank *bank) { - struct stm32h7x_flash_bank *stm32x_info = NULL; + struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; struct target *target = bank->target; uint32_t optiondata; - stm32x_info = bank->driver_priv; - int retval = stm32x_unlock_option_reg(bank); if (retval != ERROR_OK) return retval; @@ -366,13 +355,7 @@ static int stm32x_write_options(struct flash_bank *bank) optiondata = stm32x_info->option_bytes.protection & 0xff; /* Program protection WPSNPRG */ - retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_WPSN_PRG, optiondata); - if (retval != ERROR_OK) - return retval; - - optiondata = stm32x_info->option_bytes.protection2 & 0xff; - /* Program protection WPSNPRG2 */ - retval = target_write_u32(target, FLASH_REG_BASE_B1 + FLASH_WPSN_PRG, optiondata); + retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_WPSN_PRG), optiondata); if (retval != ERROR_OK) return retval; @@ -426,17 +409,7 @@ static int stm32x_protect_check(struct flash_bank *bank) } for (int i = 0; i < bank->num_sectors; i++) { - if (stm32x_info->flash_base == FLASH_REG_BASE_B0) { - if (stm32x_info->option_bytes.protection & (1 << i)) - bank->sectors[i].is_protected = 0; - else - bank->sectors[i].is_protected = 1; - } else { - if (stm32x_info->option_bytes.protection2 & (1 << i)) - bank->sectors[i].is_protected = 0; - else - bank->sectors[i].is_protected = 1; - } + bank->sectors[i].is_protected = stm32x_info->option_bytes.protection & (1 << i) ? 0 : 1; } return ERROR_OK; } @@ -515,21 +488,14 @@ static int stm32x_protect(struct flash_bank *bank, int set, int first, int last) } for (int i = first; i <= last; i++) { - if (stm32x_info->flash_base == FLASH_REG_BASE_B0) { - if (set) - stm32x_info->option_bytes.protection &= ~(1 << i); - else - stm32x_info->option_bytes.protection |= (1 << i); - } else { - if (set) - stm32x_info->option_bytes.protection2 &= ~(1 << i); - else - stm32x_info->option_bytes.protection2 |= (1 << i); - } + if (set) + stm32x_info->option_bytes.protection &= ~(1 << i); + else + stm32x_info->option_bytes.protection |= (1 << i); } - LOG_INFO("stm32x_protect, option_bytes written WRP1 0x%x , WRP2 0x%x", - (stm32x_info->option_bytes.protection & 0xff), (stm32x_info->option_bytes.protection2 & 0xff)); + LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%x", + (stm32x_info->option_bytes.protection & 0xff)); retval = stm32x_write_options(bank); if (retval != ERROR_OK) From 8d8c6df557ab1976c6df39cf712b6ef23ce8a27e Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Thu, 29 Aug 2019 15:58:39 +0200 Subject: [PATCH 034/354] flash/nor/stm32h7x: fix option bytes handling to work with both banks To achieve that we need to avoid using FLASH_REG_BASE_B0, and use bank registers instead: For dual bank devices, each option register is mapped in 2 addresses at the same offset from flash_bank_reg_base. This is true for OPTCR, OPTKEYR, OPTSR_CUR/PRG, OPTCCR according to RM0433 Rev6 (refer to section 3.9: FLASH registers) In stm32x_write_options, according to RM0433 Rev6, after OBL launch we should wait for OPTSR_CUR.BSY bit instead of FLASH_SR.QW Change-Id: Ie24a91f069d03c9233797390fc2e925c737dad90 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5291 Tested-by: jenkins Reviewed-by: Christopher Head Reviewed-by: Tomas Vanek --- src/flash/nor/stm32h7x.c | 48 ++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 1d128f3be..feb7acafd 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -79,6 +79,9 @@ #define OPT_LOCK (1 << 0) #define OPT_START (1 << 1) +/* FLASH_OPTSR register bits */ +#define OPT_BSY (1 << 0) + /* register unlock keys */ #define KEY1 0x45670123 #define KEY2 0xCDEF89AB @@ -263,7 +266,7 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank) uint32_t ctrl; struct target *target = bank->target; - int retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, &ctrl); + int retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), &ctrl); if (retval != ERROR_OK) return retval; @@ -271,15 +274,15 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank) return ERROR_OK; /* unlock option registers */ - retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTKEYR, OPTKEY1); + retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTKEYR), OPTKEY1); if (retval != ERROR_OK) return retval; - retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTKEYR, OPTKEY2); + retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTKEYR), OPTKEY2); if (retval != ERROR_OK) return retval; - retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, &ctrl); + retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), &ctrl); if (retval != ERROR_OK) return retval; @@ -310,7 +313,7 @@ static int stm32x_read_options(struct flash_bank *bank) struct target *target = bank->target; /* read current option bytes */ - int retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTSR_CUR, &optiondata); + int retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_CUR), &optiondata); if (retval != ERROR_OK) return retval; @@ -349,7 +352,7 @@ static int stm32x_write_options(struct flash_bank *bank) optiondata |= (stm32x_info->option_bytes.user3_options & 0xa3) << 24; /* program options */ - retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTSR_PRG, optiondata); + retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_PRG), optiondata); if (retval != ERROR_OK) return retval; @@ -361,12 +364,12 @@ static int stm32x_write_options(struct flash_bank *bank) optiondata = 0x40000000; /* Remove OPT error flag before programming */ - retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCCR, optiondata); + retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCCR), optiondata); if (retval != ERROR_OK) return retval; /* start programming cycle */ - retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, OPT_START); + retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), OPT_START); if (retval != ERROR_OK) return retval; @@ -374,23 +377,23 @@ static int stm32x_write_options(struct flash_bank *bank) int timeout = FLASH_ERASE_TIMEOUT; for (;;) { uint32_t status; - retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_SR, &status); + retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_CUR), &status); if (retval != ERROR_OK) { - LOG_INFO("stm32x_write_options: wait_flash_op_queue : error"); + LOG_INFO("stm32x_write_options: failed to read FLASH_OPTSR_CUR"); return retval; } - if ((status & FLASH_QW) == 0) + if ((status & OPT_BSY) == 0) break; if (timeout-- <= 0) { - LOG_INFO("wait_flash_op_queue, time out expired, status: 0x%" PRIx32 "", status); + LOG_INFO("waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32 "", status); return ERROR_FAIL; } alive_sleep(1); } /* relock option registers */ - retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, OPT_LOCK); + retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), OPT_LOCK); if (retval != ERROR_OK) return retval; @@ -904,13 +907,6 @@ COMMAND_HANDLER(stm32x_handle_lock_command) stm32x_info = bank->driver_priv; target = bank->target; - /* if we have a dual flash bank device then - * we need to perform option byte lock on bank0 only */ - if (stm32x_info->flash_base != FLASH_REG_BASE_B0) { - LOG_ERROR("Option Byte Lock Operation must use bank0"); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; @@ -921,6 +917,9 @@ COMMAND_HANDLER(stm32x_handle_lock_command) bank->driver->name); return ERROR_OK; } + + LOG_WARNING("locking the entire flash device"); + /* set readout protection */ stm32x_info->option_bytes.RDP = 0; @@ -950,13 +949,6 @@ COMMAND_HANDLER(stm32x_handle_unlock_command) stm32x_info = bank->driver_priv; target = bank->target; - /* if we have a dual flash bank device then - * we need to perform option byte unlock on bank0 only */ - if (stm32x_info->flash_base != FLASH_REG_BASE_B0) { - LOG_ERROR("Option Byte Unlock Operation must use bank0"); - return ERROR_FLASH_OPERATION_FAILED; - } - if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; @@ -967,6 +959,8 @@ COMMAND_HANDLER(stm32x_handle_unlock_command) return ERROR_OK; } + LOG_WARNING("unlocking the entire flash device"); + /* clear readout protection option byte * this will also force a device unlock if set */ stm32x_info->option_bytes.RDP = 0xAA; From 9c196b0b2b6f3ef28a646b1f17411a36ed9643a5 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 9 Sep 2019 20:38:10 +0200 Subject: [PATCH 035/354] flash/nor/stm32h7x: remove options cache and some driver enhancements functions managing option bytes cache (stm32x_read/write_options) have bee removed, and a new functions to modify a single option byte have been introduced (stm32x_write/modify_option). by the way, some helpers have been introduced to access flash registers: - stm32x_read_flash_reg(bank, offset, *value): int - stm32x_write_flash_reg(bank, offset, value): int and a new commands to read and write a single flash option register: - stm32h7x option_read - stm32h7x option_write [mask] also lock and unlock handlers' have been reduced by using the same routine (stm32x_set_rdp) and have been optimized to not write options unless there is a change in RDP level. finally, several functions have been fixed to lock flash / options in case of failure. Change-Id: I75057949ab9f5b4e0f602bafb76f9f80d53a522b Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5293 Tested-by: jenkins Reviewed-by: Christopher Head Reviewed-by: Tomas Vanek --- doc/openocd.texi | 31 +++ src/flash/nor/stm32h7x.c | 433 +++++++++++++++++++++------------------ 2 files changed, 262 insertions(+), 202 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index af1684d00..de7fe0ac1 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6769,6 +6769,37 @@ The @var{num} parameter is a value shown by @command{flash banks}. Mass erases the entire stm32h7x device. The @var{num} parameter is a value shown by @command{flash banks}. @end deffn + +@deffn Command {stm32h7x option_read} num reg_offset +Reads an option byte register from the stm32h7x device. +The @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset} +is the register offset of the option byte to read from the used bank registers' base. +For example: in STM32H74x/H75x the bank 1 registers' base is 0x52002000 and 0x52002100 for bank 2. + +Example usage: +@example +# read OPTSR_CUR +stm32h7x option_read 0 0x1c +# read WPSN_CUR1R +stm32h7x option_read 0 0x38 +# read WPSN_CUR2R +stm32h7x option_read 1 0x38 +@end example +@end deffn + +@deffn Command {stm32h7x option_write} num reg_offset value [reg_mask] +Writes an option byte register of the stm32h7x device. +The @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset} +is the register offset of the option byte to write from the used bank register base, +and @var{reg_mask} is the mask to apply when writing the register (only bits with a '1' +will be touched). + +Example usage: +@example +# swap bank 1 and bank 2 in dual bank devices, by setting SWAP_BANK_OPT bit in OPTSR_PRG +stm32h7x option_write 0 0x20 0x8000000 0x8000000 +@end example +@end deffn @end deffn @deffn {Flash Driver} stm32lx diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index feb7acafd..aec836b19 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -81,6 +81,11 @@ /* FLASH_OPTSR register bits */ #define OPT_BSY (1 << 0) +#define OPT_RDP_POS 8 +#define OPT_RDP_MASK (0xff << OPT_RDP_POS) + +/* FLASH_OPTCCR register bits */ +#define OPT_CLR_OPTCHANGEERR (1 << 30) /* register unlock keys */ #define KEY1 0x45670123 @@ -103,14 +108,6 @@ struct stm32h7x_rev { const char *str; }; -struct stm32x_options { - uint8_t RDP; - uint32_t protection; /* bank sectors's write protection (WPSN register) */ - uint8_t user_options; - uint8_t user2_options; - uint8_t user3_options; -}; - struct stm32h7x_part_info { uint16_t id; const char *device_str; @@ -129,10 +126,15 @@ struct stm32h7x_flash_bank { uint32_t idcode; uint32_t user_bank_size; uint32_t flash_base; /* Address of flash reg controller */ - struct stm32x_options option_bytes; const struct stm32h7x_part_info *part_info; }; +enum stm32h7x_opt_rdp { + OPT_RDP_L0 = 0xaa, + OPT_RDP_L1 = 0x00, + OPT_RDP_L2 = 0xcc +}; + static const struct stm32h7x_rev stm32_450_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X" }, }; @@ -152,10 +154,6 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { }, }; -static int stm32x_unlock_reg(struct flash_bank *bank); -static int stm32x_lock_reg(struct flash_bank *bank); -static int stm32x_probe(struct flash_bank *bank); - /* flash bank stm32x 0 0 */ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) @@ -174,21 +172,29 @@ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) return ERROR_OK; } -static inline uint32_t stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg) +static inline uint32_t stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset) { struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; - return reg + stm32x_info->flash_base; + return reg_offset + stm32x_info->flash_base; +} + +static inline int stm32x_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value) +{ + return target_read_u32(bank->target, stm32x_get_flash_reg(bank, reg_offset), value); +} + +static inline int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value) +{ + return target_write_u32(bank->target, stm32x_get_flash_reg(bank, reg_offset), value); } static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status) { - struct target *target = bank->target; - return target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_SR), status); + return stm32x_read_flash_reg(bank, FLASH_SR, status); } static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout) { - struct target *target = bank->target; struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; uint32_t status; int retval; @@ -221,7 +227,7 @@ static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout) if (retval == ERROR_OK) retval = ERROR_FAIL; /* If this operation fails, we ignore it and report the original retval */ - target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CCR), status); + stm32x_write_flash_reg(bank, FLASH_CCR, status); } return retval; } @@ -229,12 +235,11 @@ static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout) static int stm32x_unlock_reg(struct flash_bank *bank) { uint32_t ctrl; - struct target *target = bank->target; /* first check if not already unlocked * otherwise writing on FLASH_KEYR will fail */ - int retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), &ctrl); + int retval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl); if (retval != ERROR_OK) return retval; @@ -242,15 +247,15 @@ static int stm32x_unlock_reg(struct flash_bank *bank) return ERROR_OK; /* unlock flash registers for bank */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_KEYR), KEY1); + retval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY1); if (retval != ERROR_OK) return retval; - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_KEYR), KEY2); + retval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY2); if (retval != ERROR_OK) return retval; - retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), &ctrl); + retval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl); if (retval != ERROR_OK) return retval; @@ -264,9 +269,8 @@ static int stm32x_unlock_reg(struct flash_bank *bank) static int stm32x_unlock_option_reg(struct flash_bank *bank) { uint32_t ctrl; - struct target *target = bank->target; - int retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), &ctrl); + int retval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl); if (retval != ERROR_OK) return retval; @@ -274,15 +278,15 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank) return ERROR_OK; /* unlock option registers */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTKEYR), OPTKEY1); + retval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY1); if (retval != ERROR_OK) return retval; - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTKEYR), OPTKEY2); + retval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY2); if (retval != ERROR_OK) return retval; - retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), &ctrl); + retval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl); if (retval != ERROR_OK) return retval; @@ -294,133 +298,101 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank) return ERROR_OK; } -static int stm32x_lock_reg(struct flash_bank *bank) +static inline int stm32x_lock_reg(struct flash_bank *bank) { - struct target *target = bank->target; - - /* Lock bank reg */ - int retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; + return stm32x_write_flash_reg(bank, FLASH_CR, FLASH_LOCK); } -static int stm32x_read_options(struct flash_bank *bank) +static inline int stm32x_lock_option_reg(struct flash_bank *bank) { - uint32_t optiondata; - struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; - struct target *target = bank->target; - - /* read current option bytes */ - int retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_CUR), &optiondata); - if (retval != ERROR_OK) - return retval; - - /* decode option data */ - stm32x_info->option_bytes.user_options = optiondata & 0xfc; - stm32x_info->option_bytes.RDP = (optiondata >> 8) & 0xff; - stm32x_info->option_bytes.user2_options = (optiondata >> 16) & 0xff; - stm32x_info->option_bytes.user3_options = (optiondata >> 24) & 0xa3; - - if (stm32x_info->option_bytes.RDP != 0xAA) - LOG_INFO("Device Security Bit Set"); - - /* read current WPSN option bytes */ - retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_WPSN_CUR), &optiondata); - if (retval != ERROR_OK) - return retval; - stm32x_info->option_bytes.protection = optiondata & 0xff; - - return ERROR_OK; + return stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_LOCK); } -static int stm32x_write_options(struct flash_bank *bank) +static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value) { - struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; - struct target *target = bank->target; - uint32_t optiondata; + int retval, retval2; - int retval = stm32x_unlock_option_reg(bank); + /* unlock option bytes for modification */ + retval = stm32x_unlock_option_reg(bank); if (retval != ERROR_OK) - return retval; + goto flash_options_lock; - /* rebuild option data */ - optiondata = stm32x_info->option_bytes.user_options; - optiondata |= (stm32x_info->option_bytes.RDP << 8); - optiondata |= (stm32x_info->option_bytes.user2_options & 0xff) << 16; - optiondata |= (stm32x_info->option_bytes.user3_options & 0xa3) << 24; - - /* program options */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_PRG), optiondata); + /* write option bytes */ + retval = stm32x_write_flash_reg(bank, reg_offset, value); if (retval != ERROR_OK) - return retval; + goto flash_options_lock; - optiondata = stm32x_info->option_bytes.protection & 0xff; - /* Program protection WPSNPRG */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_WPSN_PRG), optiondata); - if (retval != ERROR_OK) - return retval; - - optiondata = 0x40000000; /* Remove OPT error flag before programming */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCCR), optiondata); + retval = stm32x_write_flash_reg(bank, FLASH_OPTCCR, OPT_CLR_OPTCHANGEERR); if (retval != ERROR_OK) - return retval; + goto flash_options_lock; /* start programming cycle */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), OPT_START); + retval = stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_START); if (retval != ERROR_OK) - return retval; + goto flash_options_lock; /* wait for completion */ int timeout = FLASH_ERASE_TIMEOUT; for (;;) { uint32_t status; - retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_CUR), &status); + retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_CUR, &status); if (retval != ERROR_OK) { - LOG_INFO("stm32x_write_options: failed to read FLASH_OPTSR_CUR"); - return retval; + LOG_INFO("stm32x_options_program: failed to read FLASH_OPTSR_CUR"); + goto flash_options_lock; } if ((status & OPT_BSY) == 0) break; if (timeout-- <= 0) { LOG_INFO("waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32 "", status); - return ERROR_FAIL; + retval = ERROR_FAIL; + goto flash_options_lock; } alive_sleep(1); } - /* relock option registers */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), OPT_LOCK); +flash_options_lock: + retval2 = stm32x_lock_option_reg(bank); + if (retval2 != ERROR_OK) + LOG_ERROR("error during the lock of flash options"); + + return (retval == ERROR_OK) ? retval2 : retval; +} + +static int stm32x_modify_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value, uint32_t mask) +{ + uint32_t data; + + int retval = stm32x_read_flash_reg(bank, reg_offset, &data); if (retval != ERROR_OK) return retval; - return ERROR_OK; + data = (data & ~mask) | (value & mask); + + return stm32x_write_option(bank, reg_offset, data); } static int stm32x_protect_check(struct flash_bank *bank) { - struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; + uint32_t protection; /* read 'write protection' settings */ - int retval = stm32x_read_options(bank); + int retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection); if (retval != ERROR_OK) { - LOG_DEBUG("unable to read option bytes"); + LOG_DEBUG("unable to read WPSN_CUR register"); return retval; } for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].is_protected = stm32x_info->option_bytes.protection & (1 << i) ? 0 : 1; + bank->sectors[i].is_protected = protection & (1 << i) ? 0 : 1; } return ERROR_OK; } static int stm32x_erase(struct flash_bank *bank, int first, int last) { - struct target *target = bank->target; - int retval; + int retval, retval2; assert(first < bank->num_sectors); assert(last < bank->num_sectors); @@ -430,7 +402,7 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last) retval = stm32x_unlock_reg(bank); if (retval != ERROR_OK) - return retval; + goto flash_lock; /* Sector Erase @@ -444,67 +416,66 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last) */ for (int i = first; i <= last; i++) { LOG_DEBUG("erase sector %d", i); - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), + retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_SER | FLASH_SNB(i) | FLASH_PSIZE_64); if (retval != ERROR_OK) { LOG_ERROR("Error erase sector %d", i); - return retval; + goto flash_lock; } - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), + retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_SER | FLASH_SNB(i) | FLASH_PSIZE_64 | FLASH_START); if (retval != ERROR_OK) { LOG_ERROR("Error erase sector %d", i); - return retval; + goto flash_lock; } retval = stm32x_wait_flash_op_queue(bank, FLASH_ERASE_TIMEOUT); if (retval != ERROR_OK) { LOG_ERROR("erase time-out or operation error sector %d", i); - return retval; + goto flash_lock; } bank->sectors[i].is_erased = 1; } - retval = stm32x_lock_reg(bank); - if (retval != ERROR_OK) { +flash_lock: + retval2 = stm32x_lock_reg(bank); + if (retval2 != ERROR_OK) LOG_ERROR("error during the lock of flash"); - return retval; - } - return ERROR_OK; + return (retval == ERROR_OK) ? retval2 : retval; } static int stm32x_protect(struct flash_bank *bank, int set, int first, int last) { struct target *target = bank->target; - struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; + uint32_t protection; if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - /* read protection settings */ - int retval = stm32x_read_options(bank); + + /* read 'write protection' settings */ + int retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection); if (retval != ERROR_OK) { - LOG_DEBUG("unable to read option bytes"); + LOG_DEBUG("unable to read WPSN_CUR register"); return retval; } for (int i = first; i <= last; i++) { if (set) - stm32x_info->option_bytes.protection &= ~(1 << i); + protection &= ~(1 << i); else - stm32x_info->option_bytes.protection |= (1 << i); + protection |= (1 << i); } - LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%x", - (stm32x_info->option_bytes.protection & 0xff)); + /* apply WRPSN mask */ + protection &= 0xff; - retval = stm32x_write_options(bank); - if (retval != ERROR_OK) - return retval; + LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%x", protection); - return ERROR_OK; + /* apply new option value */ + return stm32x_write_option(bank, FLASH_WPSN_PRG, protection); } static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, @@ -595,7 +566,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, if ((flash_sr & FLASH_ERROR) != 0) { LOG_ERROR("flash write failed, FLASH_SR = %08" PRIx32, flash_sr); /* Clear error + EOP flags but report errors */ - target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CCR), flash_sr); + stm32x_write_flash_reg(bank, FLASH_CCR, flash_sr); retval = ERROR_FAIL; } } @@ -630,7 +601,7 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, retval = stm32x_unlock_reg(bank); if (retval != ERROR_OK) - return retval; + goto flash_lock; uint32_t blocks_remaining = count / FLASH_BLOCK_SIZE; uint32_t bytes_remaining = count % FLASH_BLOCK_SIZE; @@ -663,7 +634,7 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, 4. Wait for flash operations completion */ while (blocks_remaining > 0) { - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), FLASH_PG | FLASH_PSIZE_64); + retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_PG | FLASH_PSIZE_64); if (retval != ERROR_OK) goto flash_lock; @@ -681,7 +652,7 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, } if (bytes_remaining) { - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), FLASH_PG | FLASH_PSIZE_64); + retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_PG | FLASH_PSIZE_64); if (retval != ERROR_OK) goto flash_lock; @@ -690,7 +661,7 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, goto flash_lock; /* Force Write buffer of FLASH_BLOCK_SIZE = 32 bytes */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), FLASH_PG | FLASH_PSIZE_64 | FLASH_FW); + retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_PG | FLASH_PSIZE_64 | FLASH_FW); if (retval != ERROR_OK) goto flash_lock; @@ -704,10 +675,7 @@ flash_lock: if (retval2 != ERROR_OK) LOG_ERROR("error during the lock of flash"); - if (retval == ERROR_OK) - retval = retval2; - - return retval; + return (retval == ERROR_OK) ? retval2 : retval; } static void setup_sector(struct flash_bank *bank, int start, int num, int size) @@ -891,11 +859,52 @@ static int stm32x_get_info(struct flash_bank *bank, char *buf, int buf_size) return ERROR_OK; } +static int stm32x_set_rdp(struct flash_bank *bank, enum stm32h7x_opt_rdp new_rdp) +{ + struct target *target = bank->target; + uint32_t optsr, cur_rdp; + int retval; + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_PRG, &optsr); + + if (retval != ERROR_OK) { + LOG_DEBUG("unable to read FLASH_OPTSR_PRG register"); + return retval; + } + + /* get current RDP, and check if there is a change */ + cur_rdp = (optsr & OPT_RDP_MASK) >> OPT_RDP_POS; + if (new_rdp == cur_rdp) { + LOG_INFO("the requested RDP value is already programmed"); + return ERROR_OK; + } + + switch (new_rdp) { + case OPT_RDP_L0: + LOG_WARNING("unlocking the entire flash device"); + break; + case OPT_RDP_L1: + LOG_WARNING("locking the entire flash device"); + break; + case OPT_RDP_L2: + LOG_WARNING("locking the entire flash device, irreversible"); + break; + } + + /* apply new RDP */ + optsr = (optsr & ~OPT_RDP_MASK) | (new_rdp << OPT_RDP_POS); + + /* apply new option value */ + return stm32x_write_option(bank, FLASH_OPTSR_PRG, optsr); +} + COMMAND_HANDLER(stm32x_handle_lock_command) { - struct target *target = NULL; - struct stm32h7x_flash_bank *stm32x_info = NULL; - if (CMD_ARGC < 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -904,40 +913,18 @@ COMMAND_HANDLER(stm32x_handle_lock_command) if (ERROR_OK != retval) return retval; - stm32x_info = bank->driver_priv; - target = bank->target; + retval = stm32x_set_rdp(bank, OPT_RDP_L1); - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } + if (retval != ERROR_OK) + command_print(CMD, "%s failed to lock device", bank->driver->name); + else + command_print(CMD, "%s locked", bank->driver->name); - if (stm32x_read_options(bank) != ERROR_OK) { - command_print(CMD, "%s failed to read options", - bank->driver->name); - return ERROR_OK; - } - - LOG_WARNING("locking the entire flash device"); - - /* set readout protection */ - stm32x_info->option_bytes.RDP = 0; - - if (stm32x_write_options(bank) != ERROR_OK) { - command_print(CMD, "%s failed to lock device", - bank->driver->name); - return ERROR_OK; - } - command_print(CMD, "%s locked", bank->driver->name); - - return ERROR_OK; + return retval; } COMMAND_HANDLER(stm32x_handle_unlock_command) { - struct target *target = NULL; - struct stm32h7x_flash_bank *stm32x_info = NULL; - if (CMD_ARGC < 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -946,37 +933,19 @@ COMMAND_HANDLER(stm32x_handle_unlock_command) if (ERROR_OK != retval) return retval; - stm32x_info = bank->driver_priv; - target = bank->target; + retval = stm32x_set_rdp(bank, OPT_RDP_L0); - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - if (stm32x_read_options(bank) != ERROR_OK) { - command_print(CMD, "%s failed to read options", bank->driver->name); - return ERROR_OK; - } - - LOG_WARNING("unlocking the entire flash device"); - - /* clear readout protection option byte - * this will also force a device unlock if set */ - stm32x_info->option_bytes.RDP = 0xAA; - - if (stm32x_write_options(bank) != ERROR_OK) { + if (retval != ERROR_OK) command_print(CMD, "%s failed to unlock device", bank->driver->name); - return ERROR_OK; - } - command_print(CMD, "%s unlocked.\n", bank->driver->name); + else + command_print(CMD, "%s unlocked", bank->driver->name); - return ERROR_OK; + return retval; } static int stm32x_mass_erase(struct flash_bank *bank) { - int retval; + int retval, retval2; struct target *target = bank->target; if (target->state != TARGET_HALTED) { @@ -986,28 +955,27 @@ static int stm32x_mass_erase(struct flash_bank *bank) retval = stm32x_unlock_reg(bank); if (retval != ERROR_OK) - return retval; + goto flash_lock; /* mass erase flash memory bank */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), FLASH_BER | FLASH_PSIZE_64); + retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_BER | FLASH_PSIZE_64); if (retval != ERROR_OK) - return retval; + goto flash_lock; - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), - FLASH_BER | FLASH_PSIZE_64 | FLASH_START); + retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_BER | FLASH_PSIZE_64 | FLASH_START); if (retval != ERROR_OK) - return retval; + goto flash_lock; retval = stm32x_wait_flash_op_queue(bank, 30000); if (retval != ERROR_OK) - return retval; + goto flash_lock; - retval = stm32x_lock_reg(bank); - if (retval != ERROR_OK) { +flash_lock: + retval2 = stm32x_lock_reg(bank); + if (retval2 != ERROR_OK) LOG_ERROR("error during the lock of flash"); - return retval; - } - return ERROR_OK; + + return (retval == ERROR_OK) ? retval2 : retval; } COMMAND_HANDLER(stm32x_handle_mass_erase_command) @@ -1038,6 +1006,53 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command) return retval; } +COMMAND_HANDLER(stm32x_handle_option_read_command) +{ + if (CMD_ARGC < 2) { + command_print(CMD, "stm32h7x option_read "); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (ERROR_OK != retval) + return retval; + + uint32_t reg_offset, value; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset); + retval = stm32x_read_flash_reg(bank, reg_offset, &value); + if (ERROR_OK != retval) + return retval; + + command_print(CMD, "Option Register: <0x%" PRIx32 "> = 0x%" PRIx32 "", + stm32x_get_flash_reg(bank, reg_offset), value); + + return retval; +} + +COMMAND_HANDLER(stm32x_handle_option_write_command) +{ + if (CMD_ARGC < 3) { + command_print(CMD, "stm32h7x option_write [mask]"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (ERROR_OK != retval) + return retval; + + uint32_t reg_offset, value, mask = 0xffffffff; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); + if (CMD_ARGC > 3) + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], mask); + + return stm32x_modify_option(bank, reg_offset, value, mask); +} + static const struct command_registration stm32x_exec_command_handlers[] = { { .name = "lock", @@ -1060,6 +1075,20 @@ static const struct command_registration stm32x_exec_command_handlers[] = { .usage = "bank_id", .help = "Erase entire flash device.", }, + { + .name = "option_read", + .handler = stm32x_handle_option_read_command, + .mode = COMMAND_EXEC, + .usage = "bank_id reg_offset", + .help = "Read and display device option bytes.", + }, + { + .name = "option_write", + .handler = stm32x_handle_option_write_command, + .mode = COMMAND_EXEC, + .usage = "bank_id reg_offset value [mask]", + .help = "Write device option bit fields with provided value.", + }, COMMAND_REGISTRATION_DONE }; From 20a310deb70f1d05994dc26039098af67c69faf6 Mon Sep 17 00:00:00 2001 From: Christopher Head Date: Sun, 28 Oct 2018 15:27:59 -0700 Subject: [PATCH 036/354] target/stm32h7x: Use AP2 to access DBGMCU when non HLA adapter is used The STM32H7 has three access ports. The DBGMCU component is available through AP0 at 0x5C001000 and through AP2 at 0xE00E1000. Using the latter is preferable for early configuration because it works in all power states and while SRST is asserted, whereas the former does not. Change-Id: Iaf8f01d769efb6655040060a8e1e951e1f7e50ab Signed-off-by: Christopher Head Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/4742 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- tcl/target/stm32h7x.cfg | 48 +++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/tcl/target/stm32h7x.cfg b/tcl/target/stm32h7x.cfg index 0bfc43dfd..ef9e29ac7 100644 --- a/tcl/target/stm32h7x.cfg +++ b/tcl/target/stm32h7x.cfg @@ -40,8 +40,14 @@ if {[using_jtag]} { swj_newdap $_CHIPNAME bs -irlen 5 } +if {![using_hla]} { + # STM32H7 provides an APB-AP at access port 2, which allows the access to + # the debug and trace features on the system APB System Debug Bus (APB-D). + target create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2 +} + set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 0 $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 @@ -86,24 +92,24 @@ if {![using_hla]} { $_TARGETNAME configure -event examine-end { # Enable D3 and D1 DBG clocks # DBGMCU_CR |= D3DBGCKEN | D1DBGCKEN - mmw 0x5C001004 0x00600000 0 + stm32h7x_dbgmcu_mmw 0x004 0x00600000 0 # Enable debug during low power modes (uses more power) # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP in D3 & D1 Domains - mmw 0x5C001004 0x00000187 0 + stm32h7x_dbgmcu_mmw 0x004 0x00000187 0 # Stop watchdog counters during halt # DBGMCU_APB3FZ1 |= WWDG1 - mmw 0x5C001034 0x00000040 0 + stm32h7x_dbgmcu_mmw 0x034 0x00000040 0 # DBGMCU_APB4FZ1 |= WDGLSD1 - mmw 0x5C001054 0x00040000 0 + stm32h7x_dbgmcu_mmw 0x054 0x00040000 0 } $_TARGETNAME configure -event trace-config { # Set TRACECLKEN; TRACE_MODE is set to async; when using sync # change this value accordingly to configure trace pins # assignment - mmw 0x5C001004 0x00100000 0 + stm32h7x_dbgmcu_mmw 0x004 0x00100000 0 } $_TARGETNAME configure -event reset-init { @@ -111,3 +117,33 @@ $_TARGETNAME configure -event reset-init { adapter_khz 4000 } +# like mrw, but with target selection +proc stm32h7x_mrw {used_target reg} { + set value "" + $used_target mem2array value 32 $reg 1 + return $value(0) +} + +# like mmw, but with target selection +proc stm32h7x_mmw {used_target reg setbits clearbits} { + set old [stm32h7x_mrw $used_target $reg] + set new [expr ($old & ~$clearbits) | $setbits] + $used_target mww $reg $new +} + +# mmw for dbgmcu component registers, it accepts the register offset from dbgmcu base +# this procedure will use the mem_ap on AP2 whenever possible +proc stm32h7x_dbgmcu_mmw {reg_offset setbits clearbits} { + # use $_CHIPNAME.ap2 if possible, and use the proper dbgmcu base address + if {![using_hla]} { + # get _CHIPNAME from the current target + set _CHIPNAME [regsub ".(cpu|ap)\\d*$" [target current] ""] + set used_target $_CHIPNAME.ap2 + set reg_addr [expr 0xE00E1000 + $reg_offset] + } { + set used_target [target current] + set reg_addr [expr 0x5C001000 + $reg_offset] + } + + stm32h7x_mmw $used_target $reg_addr $setbits $clearbits +} From 1fbe8450a9dd99a66f6a4035652beb400deb9277 Mon Sep 17 00:00:00 2001 From: Peter Mamonov Date: Tue, 23 Sep 2014 12:46:02 +0400 Subject: [PATCH 037/354] mips: Add MIPS64 support The patch adds support for processors implementing MIPS64 instruction set. Change-Id: I79a983dfdead81553457a0f3e9e739a9785afaac Signed-off-by: Konstantin Kostyukhin Signed-off-by: Andrey Sidorov Signed-off-by: Aleksey Kuleshov Signed-off-by: Antony Pavlov Signed-off-by: Peter Mamonov Signed-off-by: Oleksij Rempel CC: Dongxue Zhang CC: Paul Fertser CC: Salvador Arroyo CC: Spencer Oliver Reviewed-on: http://openocd.zylin.com/2321 Tested-by: jenkins Reviewed-by: Paul Fertser --- src/target/Makefile.am | 10 + src/target/mips64.c | 627 ++++++++++++++++ src/target/mips64.h | 226 ++++++ src/target/mips64_pracc.c | 1431 +++++++++++++++++++++++++++++++++++++ src/target/mips64_pracc.h | 59 ++ src/target/mips_ejtag.c | 144 ++++ src/target/mips_ejtag.h | 24 + 7 files changed, 2521 insertions(+) create mode 100644 src/target/mips64.c create mode 100644 src/target/mips64.h create mode 100644 src/target/mips64_pracc.c create mode 100644 src/target/mips64_pracc.h diff --git a/src/target/Makefile.am b/src/target/Makefile.am index afa5f49b6..2a7cc4b3b 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -32,6 +32,7 @@ noinst_LTLIBRARIES += %D%/libtarget.la if TARGET64 %C%_libtarget_la_SOURCES +=$(ARMV8_SRC) +%C%_libtarget_la_SOURCES +=$(MIPS64_SRC) endif TARGET_CORE_SRC = \ @@ -120,6 +121,13 @@ MIPS32_SRC = \ %D%/mips32_dmaacc.c \ %D%/mips_ejtag.c +MIPS64_SRC = \ + %D%/mips64.c \ + %D%/mips32_pracc.c \ + %D%/mips64_pracc.c \ + %D%/trace.c \ + %D%/mips_ejtag.c + NDS32_SRC = \ %D%/nds32.c \ %D%/nds32_reg.c \ @@ -193,10 +201,12 @@ ESIRISC_SRC = \ %D%/etm_dummy.h \ %D%/image.h \ %D%/mips32.h \ + %D%/mips64.h \ %D%/mips_m4k.h \ %D%/mips_ejtag.h \ %D%/mips32_pracc.h \ %D%/mips32_dmaacc.h \ + %D%/mips64_pracc.h \ %D%/oocd_trace.h \ %D%/register.h \ %D%/target.h \ diff --git a/src/target/mips64.c b/src/target/mips64.c new file mode 100644 index 000000000..f65aec114 --- /dev/null +++ b/src/target/mips64.c @@ -0,0 +1,627 @@ +/* + * Support for processors implementing MIPS64 instruction set + * + * Copyright (C) 2014 by Andrey Sidorov + * Copyright (C) 2014 by Aleksey Kuleshov + * Copyright (C) 2014 by Antony Pavlov + * Copyright (C) 2014 by Peter Mamonov + * + * Based on the work of: + * Copyright (C) 2008 by Spencer Oliver + * Copyright (C) 2008 by David T.L. Wong + * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if BUILD_TARGET64 == 1 + +#include "mips64.h" + +static const struct { + unsigned id; + const char *name; + enum reg_type type; + const char *group; + const char *feature; + int flag; +} mips64_regs[] = { + { 0, "r0", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 1, "r1", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 2, "r2", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 3, "r3", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 4, "r4", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 5, "r5", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 6, "r6", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 7, "r7", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 8, "r8", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 9, "r9", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 10, "r10", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 11, "r11", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 12, "r12", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 13, "r13", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 14, "r14", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 15, "r15", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 16, "r16", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 17, "r17", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 18, "r18", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 19, "r19", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 20, "r20", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 21, "r21", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 22, "r22", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 23, "r23", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 24, "r24", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 25, "r25", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 26, "r26", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 27, "r27", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 28, "r28", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 29, "r29", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 30, "r30", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 31, "r31", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 32, "lo", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { 33, "hi", REG_TYPE_UINT64, NULL, "org.gnu.gdb.mips.cpu", 0 }, + { MIPS64_NUM_CORE_REGS + 0, "pc", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cpu", 0 }, + { MIPS64_NUM_CORE_REGS + 1, "Random", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 2, "Entrylo_0", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 3, "Entrylo_1", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 4, "Context", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 5, "Pagemask", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 6, "Wired", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 7, "badvaddr", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 8, "Count", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 9, "EntryHi", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 10, "Compare", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 11, "status", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 12, "cause", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 13, "EPC", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 14, "PrID", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 15, "Config", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 16, "LLA", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 17, "WatchLo0", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 18, "WatchLo1", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 19, "WatchHi0", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 20, "WatchHi1", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 21, "Xcontext", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 22, "ChipMemCtrl", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 23, "Debug", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 24, "Perfcount, sel=0", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 25, "Perfcount, sel=1", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 26, "Perfcount, sel=2", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 27, "Perfcount, sel=3", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 28, "ECC", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 29, "CacheErr", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 30, "TagLo", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 31, "TagHi", REG_TYPE_UINT32, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 32, "DataHi", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_REGS + 33, "EEPC", REG_TYPE_UINT64, NULL, + "org.gnu.gdb.mips.cp0", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 0, "f0", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 1, "f1", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 2, "f2", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 3, "f3", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 4, "f4", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 5, "f5", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 6, "f6", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 7, "f7", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 8, "f8", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 9, "f9", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 10, "f10", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 11, "f11", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 12, "f12", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 13, "f13", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 14, "f14", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 15, "f15", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 16, "f16", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 17, "f17", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 18, "f18", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 19, "f19", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 20, "f20", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 21, "f21", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 22, "f22", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 23, "f23", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 24, "f24", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 25, "f25", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 26, "f26", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 27, "f27", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 28, "f28", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 29, "f29", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 30, "f30", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 31, "f31", REG_TYPE_IEEE_DOUBLE, NULL, + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 32, "fcsr", REG_TYPE_INT, "float", + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 33, "fir", REG_TYPE_INT, "float", + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 34, "fconfig", REG_TYPE_INT, "float", + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 35, "fccr", REG_TYPE_INT, "float", + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 36, "fexr", REG_TYPE_INT, "float", + "org.gnu.gdb.mips.fpu", 0 }, + { MIPS64_NUM_CORE_C0_REGS + 37, "fenr", REG_TYPE_INT, "float", + "org.gnu.gdb.mips.fpu", 0 }, +}; + +static int reg_type2size(enum reg_type type) +{ + switch (type) { + case REG_TYPE_UINT32: + case REG_TYPE_INT: + return 32; + case REG_TYPE_UINT64: + case REG_TYPE_IEEE_DOUBLE: + return 64; + default: + return 64; + } +} + +static int mips64_get_core_reg(struct reg *reg) +{ + int retval; + struct mips64_core_reg *mips64_reg = reg->arch_info; + struct target *target = mips64_reg->target; + struct mips64_common *mips64_target = target->arch_info; + + if (target->state != TARGET_HALTED) + return ERROR_TARGET_NOT_HALTED; + + retval = mips64_target->read_core_reg(target, mips64_reg->num); + + return retval; +} + +static int mips64_set_core_reg(struct reg *reg, uint8_t *buf) +{ + struct mips64_core_reg *mips64_reg = reg->arch_info; + struct target *target = mips64_reg->target; + uint64_t value = buf_get_u64(buf, 0, 64); + + if (target->state != TARGET_HALTED) + return ERROR_TARGET_NOT_HALTED; + + buf_set_u64(reg->value, 0, 64, value); + reg->dirty = 1; + reg->valid = 1; + + return ERROR_OK; +} + +static int mips64_read_core_reg(struct target *target, int num) +{ + uint64_t reg_value; + + /* get pointers to arch-specific information */ + struct mips64_common *mips64 = target->arch_info; + + if ((num < 0) || (num >= MIPS64_NUM_REGS)) + return ERROR_COMMAND_ARGUMENT_INVALID; + + reg_value = mips64->core_regs[num]; + buf_set_u64(mips64->core_cache->reg_list[num].value, 0, 64, reg_value); + mips64->core_cache->reg_list[num].valid = 1; + mips64->core_cache->reg_list[num].dirty = 0; + + return ERROR_OK; +} + +static int mips64_write_core_reg(struct target *target, int num) +{ + uint64_t reg_value; + + /* get pointers to arch-specific information */ + struct mips64_common *mips64 = target->arch_info; + + if ((num < 0) || (num >= MIPS64_NUM_REGS)) + return ERROR_COMMAND_ARGUMENT_INVALID; + + reg_value = buf_get_u64(mips64->core_cache->reg_list[num].value, 0, 64); + mips64->core_regs[num] = reg_value; + LOG_DEBUG("write core reg %i value 0x%" PRIx64 "", num , reg_value); + mips64->core_cache->reg_list[num].valid = 1; + mips64->core_cache->reg_list[num].dirty = 0; + + return ERROR_OK; +} + +int mips64_invalidate_core_regs(struct target *target) +{ + /* get pointers to arch-specific information */ + struct mips64_common *mips64 = target->arch_info; + unsigned int i; + + for (i = 0; i < mips64->core_cache->num_regs; i++) { + mips64->core_cache->reg_list[i].valid = 0; + mips64->core_cache->reg_list[i].dirty = 0; + } + + return ERROR_OK; +} + + +int mips64_get_gdb_reg_list(struct target *target, struct reg **reg_list[], + int *reg_list_size, enum target_register_class reg_class) +{ + /* get pointers to arch-specific information */ + struct mips64_common *mips64 = target->arch_info; + register int i; + + /* include floating point registers */ + *reg_list_size = MIPS64_NUM_REGS; + *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); + + for (i = 0; i < MIPS64_NUM_REGS; i++) + (*reg_list)[i] = &mips64->core_cache->reg_list[i]; + + return ERROR_OK; +} + +int mips64_save_context(struct target *target) +{ + int retval; + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + + retval = mips64_pracc_read_regs(ejtag_info, mips64->core_regs); + if (retval != ERROR_OK) + return retval; + + for (unsigned i = 0; i < MIPS64_NUM_REGS; i++) + retval = mips64->read_core_reg(target, i); + + return retval; +} + +int mips64_restore_context(struct target *target) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + + for (unsigned i = 0; i < MIPS64_NUM_REGS; i++) { + if (mips64->core_cache->reg_list[i].dirty) + mips64->write_core_reg(target, i); + } + + return mips64_pracc_write_regs(ejtag_info, mips64->core_regs); +} + +int mips64_arch_state(struct target *target) +{ + struct mips64_common *mips64 = target->arch_info; + struct reg *pc = &mips64->core_cache->reg_list[MIPS64_PC]; + + if (mips64->common_magic != MIPS64_COMMON_MAGIC) { + LOG_ERROR("BUG: called for a non-MIPS64 target"); + exit(-1); + } + + LOG_USER("target halted due to %s, pc: 0x%" PRIx64 "", + debug_reason_name(target), buf_get_u64(pc->value, 0, 64)); + + return ERROR_OK; +} + +static const struct reg_arch_type mips64_reg_type = { + .get = mips64_get_core_reg, + .set = mips64_set_core_reg, +}; + +int mips64_build_reg_cache(struct target *target) +{ + /* get pointers to arch-specific information */ + struct mips64_common *mips64 = target->arch_info; + struct reg_cache **cache_p, *cache; + struct mips64_core_reg *arch_info = NULL; + struct reg *reg_list = NULL; + unsigned i; + + cache = calloc(1, sizeof(*cache)); + if (!cache) { + LOG_ERROR("unable to allocate cache"); + return ERROR_FAIL; + } + + reg_list = calloc(MIPS64_NUM_REGS, sizeof(*reg_list)); + if (!reg_list) { + LOG_ERROR("unable to allocate reg_list"); + goto alloc_fail; + } + + arch_info = calloc(MIPS64_NUM_REGS, sizeof(*arch_info)); + if (!arch_info) { + LOG_ERROR("unable to allocate arch_info"); + goto alloc_fail; + } + + for (i = 0; i < MIPS64_NUM_REGS; i++) { + struct mips64_core_reg *a = &arch_info[i]; + struct reg *r = ®_list[i]; + + r->arch_info = &arch_info[i]; + r->caller_save = true; /* gdb defaults to true */ + r->exist = true; + r->feature = &a->feature; + r->feature->name = mips64_regs[i].feature; + r->group = mips64_regs[i].group; + r->name = mips64_regs[i].name; + r->number = i; + r->reg_data_type = &a->reg_data_type; + r->reg_data_type->type = mips64_regs[i].type; + r->size = reg_type2size(mips64_regs[i].type); + r->type = &mips64_reg_type; + r->value = &a->value[0]; + + a->mips64_common = mips64; + a->num = mips64_regs[i].id; + a->target = target; + } + + cache->name = "mips64 registers"; + cache->reg_list = reg_list; + cache->num_regs = MIPS64_NUM_REGS; + + cache_p = register_get_last_cache_p(&target->reg_cache); + (*cache_p) = cache; + + mips64->core_cache = cache; + + return ERROR_OK; + +alloc_fail: + free(cache); + free(reg_list); + free(arch_info); + + return ERROR_FAIL; +} + +int mips64_init_arch_info(struct target *target, struct mips64_common *mips64, + struct jtag_tap *tap) +{ + mips64->bp_scanned = false; + mips64->common_magic = MIPS64_COMMON_MAGIC; + mips64->data_break_list = NULL; + mips64->ejtag_info.tap = tap; + mips64->fast_data_area = NULL; + mips64->mips64mode32 = false; + mips64->read_core_reg = mips64_read_core_reg; + mips64->write_core_reg = mips64_write_core_reg; + + return ERROR_OK; +} + +int mips64_run_algorithm(struct target *target, int num_mem_params, + struct mem_param *mem_params, int num_reg_params, + struct reg_param *reg_params, target_addr_t entry_point, + target_addr_t exit_point, int timeout_ms, void *arch_info) +{ + /* TODO */ + return ERROR_OK; +} + +int mips64_examine(struct target *target) +{ + struct mips64_common *mips64 = target->arch_info; + + if (target_was_examined(target)) + return ERROR_OK; + + /* TODO: why we do not do mips64_configure_break_unit() here? */ + mips64->bp_scanned = false; + mips64->num_data_bpoints = 0; + mips64->num_data_bpoints_avail = 0; + mips64->num_inst_bpoints = 0; + mips64->num_inst_bpoints_avail = 0; + + target_set_examined(target); + + return ERROR_OK; +} + +static int mips64_configure_i_break_unit(struct target *target) +{ + /* get pointers to arch-specific information */ + struct mips64_common *mips64 = target->arch_info; + struct mips64_comparator *ibl; + uint64_t bpinfo; + int retval; + int i; + + /* get number of inst breakpoints */ + retval = target_read_u64(target, EJTAG64_V25_IBS, &bpinfo); + if (retval != ERROR_OK) + return retval; + + mips64->num_inst_bpoints = (bpinfo >> 24) & 0x0F; + mips64->num_inst_bpoints_avail = mips64->num_inst_bpoints; + ibl = calloc(mips64->num_inst_bpoints, sizeof(*ibl)); + if (!ibl) { + LOG_ERROR("unable to allocate inst_break_list"); + return ERROR_FAIL; + } + + for (i = 0; i < mips64->num_inst_bpoints; i++) + ibl[i].reg_address = EJTAG64_V25_IBA0 + (0x100 * i); + + mips64->inst_break_list = ibl; + /* clear IBIS reg */ + retval = target_write_u64(target, EJTAG64_V25_IBS, 0); + if (retval != ERROR_OK) + return retval; + + return ERROR_OK; +} + +static int mips64_configure_d_break_unit(struct target *target) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips64_comparator *dbl; + uint64_t bpinfo; + int retval; + int i; + + /* get number of data breakpoints */ + retval = target_read_u64(target, EJTAG64_V25_DBS, &bpinfo); + if (retval != ERROR_OK) + return retval; + + mips64->num_data_bpoints = (bpinfo >> 24) & 0x0F; + mips64->num_data_bpoints_avail = mips64->num_data_bpoints; + + dbl = calloc(mips64->num_data_bpoints, sizeof(*dbl)); + + if (!dbl) { + LOG_ERROR("unable to allocate data_break_list"); + return ERROR_FAIL; + } + + for (i = 0; i < mips64->num_data_bpoints; i++) + dbl[i].reg_address = EJTAG64_V25_DBA0 + (0x100 * i); + + mips64->data_break_list = dbl; + + /* clear DBIS reg */ + retval = target_write_u64(target, EJTAG64_V25_DBS, 0); + if (retval != ERROR_OK) + return retval; + + return ERROR_OK; +} + +int mips64_configure_break_unit(struct target *target) +{ + struct mips64_common *mips64 = target->arch_info; + uint64_t dcr; + int retval; + + if (mips64->bp_scanned) + return ERROR_OK; + + /* get info about breakpoint support */ + retval = target_read_u64(target, EJTAG64_DCR, &dcr); + if (retval != ERROR_OK) + return retval; + + if (dcr & EJTAG64_DCR_IB) { + retval = mips64_configure_i_break_unit(target); + if (retval != ERROR_OK) + return retval; + } + + if (dcr & EJTAG64_DCR_DB) { + retval = mips64_configure_d_break_unit(target); + if (retval != ERROR_OK) + return retval; + } + + LOG_DEBUG("DCR 0x%" PRIx64 " numinst %i numdata %i", dcr, + mips64->num_inst_bpoints, mips64->num_data_bpoints); + + mips64->bp_scanned = true; + + return ERROR_OK; +} + +int mips64_enable_interrupts(struct target *target, bool enable) +{ + int retval; + bool update = false; + uint64_t dcr; + + /* read debug control register */ + retval = target_read_u64(target, EJTAG64_DCR, &dcr); + if (retval != ERROR_OK) + return retval; + + if (enable) { + if (!(dcr & EJTAG64_DCR_INTE)) { + /* enable interrupts */ + dcr |= EJTAG64_DCR_INTE; + update = true; + } + } else { + if (dcr & EJTAG64_DCR_INTE) { + /* disable interrupts */ + dcr &= ~(uint64_t)EJTAG64_DCR_INTE; + update = true; + } + } + + if (update) { + retval = target_write_u64(target, EJTAG64_DCR, dcr); + if (retval != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + +#endif /* BUILD_TARGET64 */ diff --git a/src/target/mips64.h b/src/target/mips64.h new file mode 100644 index 000000000..3453e4ed1 --- /dev/null +++ b/src/target/mips64.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Support for processors implementing MIPS64 instruction set + * + * Copyright (C) 2014 by Andrey Sidorov + * Copyright (C) 2014 by Aleksey Kuleshov + * Copyright (C) 2014-2019 by Peter Mamonov + * + * Based on the work of: + * Copyright (C) 2008 by Spencer Oliver + * Copyright (C) 2008 by David T.L. Wong + * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev + */ + +#ifndef OPENOCD_TARGET_MIPS64_H +#define OPENOCD_TARGET_MIPS64_H + +#include "target.h" +#include "register.h" +#include "mips64_pracc.h" + +#define MIPS64_COMMON_MAGIC 0xB640B640 + +/* MIPS64 CP0 registers */ +#define MIPS64_C0_INDEX 0 +#define MIPS64_C0_RANDOM 1 +#define MIPS64_C0_ENTRYLO0 2 +#define MIPS64_C0_ENTRYLO1 3 +#define MIPS64_C0_CONTEXT 4 +#define MIPS64_C0_PAGEMASK 5 +#define MIPS64_C0_WIRED 6 +#define MIPS64_C0_BADVADDR 8 +#define MIPS64_C0_COUNT 9 +#define MIPS64_C0_ENTRYHI 10 +#define MIPS64_C0_COMPARE 11 +#define MIPS64_C0_STATUS 12 +#define MIPS64_C0_CAUSE 13 +#define MIPS64_C0_EPC 14 +#define MIPS64_C0_PRID 15 +#define MIPS64_C0_CONFIG 16 +#define MIPS64_C0_LLA 17 +#define MIPS64_C0_WATCHLO 18 +#define MIPS64_C0_WATCHHI 19 +#define MIPS64_C0_XCONTEXT 20 +#define MIPS64_C0_MEMCTRL 22 +#define MIPS64_C0_DEBUG 23 +#define MIPS64_C0_DEPC 24 +#define MIPS64_C0_PERFCOUNT 25 +#define MIPS64_C0_ECC 26 +#define MIPS64_C0_CACHERR 27 +#define MIPS64_C0_TAGLO 28 +#define MIPS64_C0_TAGHI 29 +#define MIPS64_C0_DATAHI 29 +#define MIPS64_C0_EEPC 30 + +/* MIPS64 CP1 registers */ +#define MIPS64_C1_FIR 0 +#define MIPS64_C1_FCONFIG 24 +#define MIPS64_C1_FCSR 31 +#define MIPS64_C1_FCCR 25 +#define MIPS64_C1_FEXR 26 +#define MIPS64_C1_FENR 28 + +/* offsets into mips64 register cache */ +#define MIPS64_NUM_CORE_REGS 34 +#define MIPS64_NUM_C0_REGS 34 +#define MIPS64_NUM_FP_REGS 38 + +#define MIPS64_NUM_REGS (MIPS64_NUM_CORE_REGS + \ + MIPS64_NUM_C0_REGS + \ + MIPS64_NUM_FP_REGS) + +#define MIPS64_NUM_CORE_C0_REGS (MIPS64_NUM_CORE_REGS + MIPS64_NUM_C0_REGS) + +#define MIPS64_PC MIPS64_NUM_CORE_REGS + +struct mips64_comparator { + bool used; + uint64_t bp_value; + uint64_t reg_address; +}; + +struct mips64_common { + uint32_t common_magic; + void *arch_info; + struct reg_cache *core_cache; + struct mips_ejtag ejtag_info; + uint64_t core_regs[MIPS64_NUM_REGS]; + + struct working_area *fast_data_area; + + bool bp_scanned; + int num_inst_bpoints; + int num_data_bpoints; + int num_inst_bpoints_avail; + int num_data_bpoints_avail; + struct mips64_comparator *inst_break_list; + struct mips64_comparator *data_break_list; + + /* register cache to processor synchronization */ + int (*read_core_reg)(struct target *target, int num); + int (*write_core_reg)(struct target *target, int num); + + bool mips64mode32; +}; + +struct mips64_core_reg { + uint32_t num; + struct target *target; + struct mips64_common *mips64_common; + uint8_t value[8]; + struct reg_feature feature; + struct reg_data_type reg_data_type; +}; + +#define MIPS64_OP_SRL 0x02 +#define MIPS64_OP_BEQ 0x04 +#define MIPS64_OP_BNE 0x05 +#define MIPS64_OP_ADDI 0x08 +#define MIPS64_OP_ANDI 0x0c +#define MIPS64_OP_DADDI 0x18 +#define MIPS64_OP_DADDIU 0x19 +#define MIPS64_OP_AND 0x24 +#define MIPS64_OP_LUI 0x0F +#define MIPS64_OP_LW 0x23 +#define MIPS64_OP_LD 0x37 +#define MIPS64_OP_LBU 0x24 +#define MIPS64_OP_LHU 0x25 +#define MIPS64_OP_MFHI 0x10 +#define MIPS64_OP_MTHI 0x11 +#define MIPS64_OP_MFLO 0x12 +#define MIPS64_OP_MTLO 0x13 +#define MIPS64_OP_SB 0x28 +#define MIPS64_OP_SH 0x29 +#define MIPS64_OP_SW 0x2B +#define MIPS64_OP_SD 0x3F +#define MIPS64_OP_ORI 0x0D +#define MIPS64_OP_JR 0x08 + +#define MIPS64_OP_COP0 0x10 +#define MIPS64_OP_COP1 0x11 +#define MIPS64_OP_COP2 0x12 + +#define MIPS64_COP_MF 0x00 +#define MIPS64_COP_DMF 0x01 +#define MIPS64_COP_MT 0x04 +#define MIPS64_COP_DMT 0x05 +#define MIPS64_COP_CF 0x02 +#define MIPS64_COP_CT 0x06 + +#define MIPS64_R_INST(opcode, rs, rt, rd, shamt, funct) \ +(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((shamt) << 6) | (funct)) +#define MIPS64_I_INST(opcode, rs, rt, immd) (((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | (immd)) +#define MIPS64_J_INST(opcode, addr) (((opcode) << 26) | (addr)) + +#define MIPS64_NOP 0 +#define MIPS64_ADDI(tar, src, val) MIPS64_I_INST(MIPS64_OP_ADDI, src, tar, val) +#define MIPS64_DADDI(tar, src, val) MIPS64_I_INST(MIPS64_OP_DADDI, src, tar, val) +#define MIPS64_DADDIU(tar, src, val) MIPS64_I_INST(MIPS64_OP_DADDIU, src, tar, val) +#define MIPS64_AND(reg, off, val) MIPS64_R_INST(0, off, val, reg, 0, MIPS64_OP_AND) +#define MIPS64_ANDI(d, s, im) MIPS64_I_INST(MIPS64_OP_ANDI, s, d, im) +#define MIPS64_SRL(d, w, sh) MIPS64_R_INST(0, 0, w, d, sh, MIPS64_OP_SRL) +#define MIPS64_B(off) MIPS64_BEQ(0, 0, off) +#define MIPS64_BEQ(src, tar, off) MIPS64_I_INST(MIPS64_OP_BEQ, src, tar, off) +#define MIPS64_BNE(src, tar, off) MIPS64_I_INST(MIPS64_OP_BNE, src, tar, off) +#define MIPS64_MFC0(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_MF, gpr, cpr, 0, sel) +#define MIPS64_DMFC0(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_DMF, gpr, cpr, 0, sel) +#define MIPS64_MTC0(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_MT, gpr, cpr, 0, sel) +#define MIPS64_DMTC0(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_DMT, gpr, cpr, 0, sel) +#define MIPS64_MFC1(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_MF, gpr, cpr, 0, 0) +#define MIPS64_DMFC1(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_DMF, gpr, cpr, 0, 0) +#define MIPS64_MTC1(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_MT, gpr, cpr, 0, 0) +#define MIPS64_DMTC1(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_DMT, gpr, cpr, 0, 0) +#define MIPS64_MFC2(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_MF, gpr, cpr, 0, sel) +#define MIPS64_MTC2(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_MT, gpr, cpr, 0, sel) +#define MIPS64_CFC1(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_CF, gpr, cpr, 0, 0) +#define MIPS64_CTC1(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_CT, gpr, cpr, 0, 0) +#define MIPS64_CFC2(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_CF, gpr, cpr, 0, sel) +#define MIPS64_CTC2(gpr, cpr, sel) MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_CT, gpr, cpr, 0, sel) +#define MIPS64_LBU(reg, off, base) MIPS64_I_INST(MIPS64_OP_LBU, base, reg, off) +#define MIPS64_LHU(reg, off, base) MIPS64_I_INST(MIPS64_OP_LHU, base, reg, off) +#define MIPS64_LUI(reg, val) MIPS64_I_INST(MIPS64_OP_LUI, 0, reg, val) +#define MIPS64_LW(reg, off, base) MIPS64_I_INST(MIPS64_OP_LW, base, reg, off) +#define MIPS64_LD(reg, off, base) MIPS64_I_INST(MIPS64_OP_LD, base, reg, off) +#define MIPS64_MFLO(reg) MIPS64_R_INST(0, 0, 0, reg, 0, MIPS64_OP_MFLO) +#define MIPS64_MFHI(reg) MIPS64_R_INST(0, 0, 0, reg, 0, MIPS64_OP_MFHI) +#define MIPS64_MTLO(reg) MIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_MTLO) +#define MIPS64_MTHI(reg) MIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_MTHI) +#define MIPS64_ORI(src, tar, val) MIPS64_I_INST(MIPS64_OP_ORI, src, tar, val) +#define MIPS64_SB(reg, off, base) MIPS64_I_INST(MIPS64_OP_SB, base, reg, off) +#define MIPS64_SH(reg, off, base) MIPS64_I_INST(MIPS64_OP_SH, base, reg, off) +#define MIPS64_SW(reg, off, base) MIPS64_I_INST(MIPS64_OP_SW, base, reg, off) +#define MIPS64_SD(reg, off, base) MIPS64_I_INST(MIPS64_OP_SD, base, reg, off) +#define MIPS64_CACHE(op, reg, off) (47 << 26 | (reg) << 21 | (op) << 16 | (off)) +#define MIPS64_SYNCI(reg, off) (1 << 26 | (reg) << 21 | 0x1f << 16 | (off)) +#define MIPS64_JR(reg) MIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_JR) + +/* ejtag specific instructions */ +#define MIPS64_DRET 0x4200001F +#define MIPS64_SDBBP 0x7000003F +#define MIPS64_SDBBP_LE 0x3f000007 +#define MIPS64_SDBBP_SIZE 4 +#define MIPS16_SDBBP_SIZE 2 + +#define MIPS64_SYNC 0x0000000F + +int mips64_arch_state(struct target *target); +int mips64_init_arch_info(struct target *target, struct mips64_common *mips64, struct jtag_tap *tap); +int mips64_restore_context(struct target *target); +int mips64_save_context(struct target *target); +int mips64_build_reg_cache(struct target *target); +int mips64_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, + int num_reg_params, struct reg_param *reg_params, + target_addr_t entry_point, target_addr_t exit_point, + int timeout_ms, void *arch_info); +int mips64_configure_break_unit(struct target *target); +int mips64_enable_interrupts(struct target *target, bool enable); +int mips64_examine(struct target *target); + +int mips64_register_commands(struct command_context *cmd_ctx); +int mips64_invalidate_core_regs(struct target *target); +int mips64_get_gdb_reg_list(struct target *target, + struct reg **reg_list[], int *reg_list_size, + enum target_register_class reg_class); + +#endif /* OPENOCD_TARGET_MIPS64_H */ diff --git a/src/target/mips64_pracc.c b/src/target/mips64_pracc.c new file mode 100644 index 000000000..57addc72a --- /dev/null +++ b/src/target/mips64_pracc.c @@ -0,0 +1,1431 @@ +/* + * Support for processors implementing MIPS64 instruction set + * + * Copyright (C) 2014 by Andrey Sidorov + * Copyright (C) 2014 by Aleksey Kuleshov + * Copyright (C) 2014-2019 by Peter Mamonov + * + * Based on the work of: + * Copyright (C) 2008 by Spencer Oliver + * Copyright (C) 2008 by David T.L. Wong + * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if BUILD_TARGET64 == 1 + +#include "mips64.h" +#include "mips64_pracc.h" + +#include "time_support.h" + +#define STACK_DEPTH 32 + +typedef struct { + uint64_t *local_iparam; + unsigned num_iparam; + uint64_t *local_oparam; + unsigned num_oparam; + const uint32_t *code; + unsigned code_len; + uint64_t stack[STACK_DEPTH]; + unsigned stack_offset; + struct mips_ejtag *ejtag_info; +} mips64_pracc_context; + +static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl) +{ + uint32_t ejtag_ctrl; + int nt = 5; + int rc; + + while (1) { + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); + ejtag_ctrl = ejtag_info->ejtag_ctrl; + rc = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); + if (rc != ERROR_OK) + return rc; + + if (ejtag_ctrl & EJTAG_CTRL_PRACC) + break; + LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n"); + if (nt == 0) + return ERROR_JTAG_DEVICE_ERROR; + nt--; + } + + *ctrl = ejtag_ctrl; + return ERROR_OK; +} + +static int mips64_pracc_exec_read(mips64_pracc_context *ctx, uint64_t address) +{ + struct mips_ejtag *ejtag_info = ctx->ejtag_info; + unsigned offset; + uint32_t ejtag_ctrl; + uint64_t data; + int rc; + + if ((address >= MIPS64_PRACC_PARAM_IN) + && (address < MIPS64_PRACC_PARAM_IN + ctx->num_iparam * MIPS64_PRACC_DATA_STEP)) { + + offset = (address - MIPS64_PRACC_PARAM_IN) / MIPS64_PRACC_DATA_STEP; + + if (offset >= MIPS64_PRACC_PARAM_IN_SIZE) { + LOG_ERROR("Error: iparam size exceeds MIPS64_PRACC_PARAM_IN_SIZE"); + return ERROR_JTAG_DEVICE_ERROR; + } + + if (ctx->local_iparam == NULL) { + LOG_ERROR("Error: unexpected reading of input parameter"); + return ERROR_JTAG_DEVICE_ERROR; + } + + data = ctx->local_iparam[offset]; + LOG_DEBUG("Reading %" PRIx64 " at %" PRIx64, data, address); + + } else if ((address >= MIPS64_PRACC_PARAM_OUT) + && (address < MIPS64_PRACC_PARAM_OUT + ctx->num_oparam * MIPS64_PRACC_DATA_STEP)) { + + offset = (address - MIPS64_PRACC_PARAM_OUT) / MIPS64_PRACC_DATA_STEP; + if (ctx->local_oparam == NULL) { + LOG_ERROR("Error: unexpected reading of output parameter"); + return ERROR_JTAG_DEVICE_ERROR; + } + + data = ctx->local_oparam[offset]; + LOG_DEBUG("Reading %" PRIx64 " at %" PRIx64, data, address); + + } else if ((address >= MIPS64_PRACC_TEXT) + && (address < MIPS64_PRACC_TEXT + ctx->code_len * MIPS64_PRACC_ADDR_STEP)) { + + offset = ((address & ~7ull) - MIPS64_PRACC_TEXT) / MIPS64_PRACC_ADDR_STEP; + data = (uint64_t)ctx->code[offset] << 32; + if (offset + 1 < ctx->code_len) + data |= (uint64_t)ctx->code[offset + 1]; + + LOG_DEBUG("Running commands %" PRIx64 " at %" PRIx64, data, + address); + + } else if ((address & ~7llu) == MIPS64_PRACC_STACK) { + + /* load from our debug stack */ + if (ctx->stack_offset == 0) { + LOG_ERROR("Error reading from stack: stack is empty"); + return ERROR_JTAG_DEVICE_ERROR; + } + + data = ctx->stack[--ctx->stack_offset]; + LOG_DEBUG("Reading %" PRIx64 " at %" PRIx64, data, address); + + } else { + /* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back + * to start of debug vector */ + + data = 0; + LOG_ERROR("Error reading unexpected address %" PRIx64, address); + return ERROR_JTAG_DEVICE_ERROR; + } + + /* Send the data out */ + mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA); + rc = mips_ejtag_drscan_64(ctx->ejtag_info, &data); + if (rc != ERROR_OK) + return rc; + + /* Clear the access pending bit (let the processor eat!) */ + + ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC; + mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL); + rc = mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl); + if (rc != ERROR_OK) + return rc; + + jtag_add_clocks(5); + + return jtag_execute_queue(); +} + +static int mips64_pracc_exec_write(mips64_pracc_context *ctx, uint64_t address) +{ + uint32_t ejtag_ctrl; + uint64_t data; + unsigned offset; + struct mips_ejtag *ejtag_info = ctx->ejtag_info; + int rc; + + mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA); + rc = mips_ejtag_drscan_64(ctx->ejtag_info, &data); + if (rc != ERROR_OK) + return rc; + + /* Clear access pending bit */ + ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC; + mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL); + rc = mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl); + if (rc != ERROR_OK) + return rc; + + jtag_add_clocks(5); + rc = jtag_execute_queue(); + if (rc != ERROR_OK) + return rc; + + LOG_DEBUG("Writing %" PRIx64 " at %" PRIx64, data, address); + + if ((address >= MIPS64_PRACC_PARAM_IN) + && (address < MIPS64_PRACC_PARAM_IN + ctx->num_iparam * MIPS64_PRACC_DATA_STEP)) { + offset = (address - MIPS64_PRACC_PARAM_IN) / MIPS64_PRACC_DATA_STEP; + if (ctx->local_iparam == NULL) { + LOG_ERROR("Error: unexpected writing of input parameter"); + return ERROR_JTAG_DEVICE_ERROR; + } + ctx->local_iparam[offset] = data; + } else if ((address >= MIPS64_PRACC_PARAM_OUT) + && (address < MIPS64_PRACC_PARAM_OUT + ctx->num_oparam * MIPS64_PRACC_DATA_STEP)) { + offset = (address - MIPS64_PRACC_PARAM_OUT) / MIPS64_PRACC_DATA_STEP; + if (ctx->local_oparam == NULL) { + LOG_ERROR("Error: unexpected writing of output parameter"); + return ERROR_JTAG_DEVICE_ERROR; + } + ctx->local_oparam[offset] = data; + } else if (address == MIPS64_PRACC_STACK) { + /* save data onto our stack */ + if (ctx->stack_offset >= STACK_DEPTH) { + LOG_ERROR("Error: PrAcc stack depth exceeded"); + return ERROR_FAIL; + } + ctx->stack[ctx->stack_offset++] = data; + } else { + LOG_ERROR("Error writing unexpected address 0x%" PRIx64, address); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +} + +int mips64_pracc_exec(struct mips_ejtag *ejtag_info, + unsigned code_len, const uint32_t *code, + unsigned num_param_in, uint64_t *param_in, + unsigned num_param_out, uint64_t *param_out) +{ + uint32_t ejtag_ctrl; + uint64_t address = 0, address_prev = 0, data; + mips64_pracc_context ctx; + int retval; + int pass = 0; + bool first_time_call = true; + unsigned i; + + for (i = 0; i < code_len; i++) + LOG_DEBUG("%08x", code[i]); + + ctx.local_iparam = param_in; + ctx.local_oparam = param_out; + ctx.num_iparam = num_param_in; + ctx.num_oparam = num_param_out; + ctx.code = code; + ctx.code_len = code_len; + ctx.ejtag_info = ejtag_info; + ctx.stack_offset = 0; + + while (true) { + uint32_t address32; + retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl); + if (retval != ERROR_OK) { + LOG_DEBUG("ERROR wait_for_pracc_rw"); + return retval; + } + if (pass) + address_prev = address; + else + address_prev = 0; + address32 = data = 0; + + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); + mips_ejtag_drscan_32(ejtag_info, &address32); + LOG_DEBUG("-> %08x", address32); + address = 0xffffffffff200000ull | address32; + + int psz = (ejtag_ctrl >> 29) & 3; + int address20 = address & 7; + switch (psz) { + case 3: + if (address20 != 7) { + LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz, address20); + return ERROR_FAIL; + } + address &= ~7ull; + break; + case 2: + if (address20 != 0 && address20 != 4) { + LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz, address20); + return ERROR_FAIL; + } + break; + default: + LOG_ERROR("PSZ=%d ADDRESS[2:0]=%d: not supported", psz, address20); + return ERROR_FAIL; + } + + if (first_time_call && address != MIPS64_PRACC_TEXT) { + LOG_ERROR("Error reading address " TARGET_ADDR_FMT " (0x%08llx expected)", + address, MIPS64_PRACC_TEXT); + return ERROR_JTAG_DEVICE_ERROR; + } + + first_time_call = false; + + /* Check for read or write */ + if (ejtag_ctrl & EJTAG_CTRL_PRNW) { + retval = mips64_pracc_exec_write(&ctx, address); + if (retval != ERROR_OK) { + printf("ERROR mips64_pracc_exec_write\n"); + return retval; + } + } else { + /* Check to see if its reading at the debug vector. The first pass through + * the module is always read at the vector, so the first one we allow. When + * the second read from the vector occurs we are done and just exit. */ + if ((address == MIPS64_PRACC_TEXT) && (pass++)) { + LOG_DEBUG("@MIPS64_PRACC_TEXT, address_prev=%" PRIx64, address_prev); + break; + } + retval = mips64_pracc_exec_read(&ctx, address); + if (retval != ERROR_OK) { + printf("ERROR mips64_pracc_exec_read\n"); + return retval; + } + + } + } + + /* stack sanity check */ + if (ctx.stack_offset != 0) + LOG_ERROR("Pracc Stack not zero"); + + return ERROR_OK; +} + +static int mips64_pracc_read_u64(struct mips_ejtag *ejtag_info, uint64_t addr, + uint64_t *buf) +{ + const uint32_t code[] = { + /* move $15 to COP0 DeSave */ + MIPS64_DMTC0(15, 31, 0), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + /* sd $8, ($15) */ + MIPS64_SD(8, 0, 15), + /* load R8 @ param_in[0] = address */ + MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15), + /* ld $8, 0($8), Load $8 with the word @mem[$8] */ + MIPS64_LD(8, 0, 8), + /* sd $8, 0($15) */ + MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15), + /* ld $8, ($15) */ + MIPS64_LD(8, 0, 15), + MIPS64_SYNC, + /* b start */ + MIPS64_B(NEG16(10)), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + uint64_t param_in[1]; + param_in[0] = addr; + + LOG_DEBUG("enter mips64_pracc_exec"); + return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + ARRAY_SIZE(param_in), param_in, 1, (uint64_t *) buf); +} + +static int mips64_pracc_read_mem64(struct mips_ejtag *ejtag_info, uint64_t addr, + unsigned count, uint64_t *buf) +{ + int retval = ERROR_OK; + + for (unsigned i = 0; i < count; i++) { + retval = mips64_pracc_read_u64(ejtag_info, addr + 8*i, &buf[i]); + if (retval != ERROR_OK) + return retval; + } + return retval; +} + +static int mips64_pracc_read_u32(struct mips_ejtag *ejtag_info, uint64_t addr, + uint32_t *buf) +{ + const uint32_t code[] = { + /* move $15 to COP0 DeSave */ + MIPS64_DMTC0(15, 31, 0), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + /* sd $8, ($15) */ + MIPS64_SD(8, 0, 15), + /* load R8 @ param_in[0] = address */ + MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15), + /* lw $8, 0($8), Load $8 with the word @mem[$8] */ + MIPS64_LW(8, 0, 8), + /* sd $8, 0($9) */ + MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15), + /* ld $8, ($15) */ + MIPS64_LD(8, 0, 15), + MIPS64_SYNC, + /* b start */ + MIPS64_B(NEG16(10)), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + int retval = ERROR_OK; + uint64_t param_in[1]; + uint64_t param_out[1]; + + param_in[0] = addr; + + LOG_DEBUG("enter mips64_pracc_exec"); + retval = mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + 1, param_in, 1, param_out); + buf[0] = (uint32_t) param_out[0]; + return retval; +} + +static int mips64_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint64_t addr, + unsigned count, uint32_t *buf) +{ + int retval = ERROR_OK; + + for (unsigned i = 0; i < count; i++) { + retval = mips64_pracc_read_u32(ejtag_info, addr + 4 * i, &buf[i]); + if (retval != ERROR_OK) + return retval; + } + return retval; +} + +static int mips64_pracc_read_u16(struct mips_ejtag *ejtag_info, uint64_t addr, + uint16_t *buf) +{ + const uint32_t code[] = { + /* move $15 to COP0 DeSave */ + MIPS64_DMTC0(15, 31, 0), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + /* sd $8, ($15) */ + MIPS64_SD(8, 0, 15), + /* load R8 @ param_in[0] = address */ + MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15), + /* lw $8, 0($8), Load $8 with the word @mem[$8] */ + MIPS64_LHU(8, 0, 8), + /* sd $8, 0($9) */ + MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15), + /* ld $8, ($15) */ + MIPS64_LD(8, 0, 15), + MIPS64_SYNC, + /* b start */ + MIPS64_B(NEG16(10)), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + int retval; + uint64_t param_in[1]; + uint64_t param_out[1]; + + param_in[0] = addr; + + LOG_DEBUG("enter mips64_pracc_exec"); + retval = mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + 1, param_in, 1, param_out); + buf[0] = (uint16_t)param_out[0]; + return retval; +} + +static int mips64_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint64_t addr, + unsigned count, uint16_t *buf) +{ + int retval = ERROR_OK; + + for (unsigned i = 0; i < count; i++) { + retval = mips64_pracc_read_u16(ejtag_info, addr + 2*i, &buf[i]); + if (retval != ERROR_OK) + return retval; + } + return retval; +} + +static int mips64_pracc_read_u8(struct mips_ejtag *ejtag_info, uint64_t addr, + uint8_t *buf) +{ + const uint32_t code[] = { + /* move $15 to COP0 DeSave */ + MIPS64_DMTC0(15, 31, 0), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + /* sd $8, ($15) */ + MIPS64_SD(8, 0, 15), + /* load R8 @ param_in[0] = address */ + MIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15), + /* lw $8, 0($8), Load $8 with the word @mem[$8] */ + MIPS64_LBU(8, 0, 8), + /* sd $8, 0($9) */ + MIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15), + /* ld $8, ($15) */ + MIPS64_LD(8, 0, 15), + MIPS64_SYNC, + /* b start */ + MIPS64_B(NEG16(10)), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + int retval; + uint64_t param_in[1]; + uint64_t param_out[1]; + + param_in[0] = addr; + + LOG_DEBUG("enter mips64_pracc_exec"); + retval = mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + 1, param_in, 1, param_out); + buf[0] = (uint8_t)param_out[0]; + return retval; +} + +static int mips64_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint64_t addr, + unsigned count, uint8_t *buf) +{ + int retval = ERROR_OK; + + for (unsigned i = 0; i < count; i++) { + retval = mips64_pracc_read_u8(ejtag_info, addr + i, &buf[i]); + if (retval != ERROR_OK) + return retval; + } + return retval; +} + +int mips64_pracc_read_mem(struct mips_ejtag *ejtag_info, uint64_t addr, + unsigned size, unsigned count, void *buf) +{ + switch (size) { + case 1: + return mips64_pracc_read_mem8(ejtag_info, addr, count, buf); + case 2: + return mips64_pracc_read_mem16(ejtag_info, addr, count, buf); + case 4: + return mips64_pracc_read_mem32(ejtag_info, addr, count, buf); + case 8: + return mips64_pracc_read_mem64(ejtag_info, addr, count, buf); + } + return ERROR_FAIL; +} + +static int mips64_pracc_write_u64(struct mips_ejtag *ejtag_info, uint64_t addr, + uint64_t *buf) +{ + const uint32_t code[] = { + /* move $15 to COP0 DeSave */ + MIPS64_DMTC0(15, 31, 0), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + /* sd $8, ($15) */ + MIPS64_SD(8, 0, 15), + /* sd $9, ($15) */ + MIPS64_SD(9, 0, 15), + /* load R8 @ param_in[1] = data */ + MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN)-8), 15), + /* load R9 @ param_in[0] = address */ + MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15), + /* sd $8, 0($9) */ + MIPS64_SD(8, 0, 9), + MIPS64_SYNCI(9, 0), + /* ld $9, ($15) */ + MIPS64_LD(9, 0, 15), + /* ld $8, ($15) */ + MIPS64_LD(8, 0, 15), + MIPS64_SYNC, + /* b start */ + MIPS64_B(NEG16(13)), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + /* TODO remove array */ + uint64_t param_in[2]; + param_in[0] = addr; + param_in[1] = *buf; + + LOG_DEBUG("enter mips64_pracc_exec"); + return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + ARRAY_SIZE(param_in), param_in, 0, NULL); +} + +static int mips64_pracc_write_mem64(struct mips_ejtag *ejtag_info, + uint64_t addr, unsigned count, uint64_t *buf) +{ + int retval = ERROR_OK; + + for (unsigned i = 0; i < count; i++) { + retval = mips64_pracc_write_u64(ejtag_info, addr + 8 * i, &buf[i]); + if (retval != ERROR_OK) + return retval; + } + return retval; +} + +static int mips64_pracc_write_u32(struct mips_ejtag *ejtag_info, uint64_t addr, + uint32_t *buf) +{ + const uint32_t code[] = { + MIPS64_DMTC0(15, 31, 0), + /* move $15 to COP0 DeSave */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + MIPS64_SD(8, 0, 15), + /* sd $8, ($15) */ + MIPS64_SD(9, 0, 15), + /* sd $9, ($15) */ + MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN) - 8), 15), + /* load R8 @ param_in[1] = data */ + MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15), + /* load R9 @ param_in[0] = address */ + MIPS64_SW(8, 0, 9), + /* sw $8, 0($9) */ + MIPS64_SYNCI(9, 0), + MIPS64_LD(9, 0, 15), + /* ld $9, ($15) */ + MIPS64_LD(8, 0, 15), + /* ld $8, ($15) */ + MIPS64_SYNC, + MIPS64_B(NEG16(13)), + /* b start */ + MIPS64_DMFC0(15, 31, 0), + /* move COP0 DeSave to $15 */ + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + /* TODO remove array */ + uint64_t param_in[1 + 1]; + param_in[0] = addr; + param_in[1] = *buf; + + LOG_DEBUG("enter mips64_pracc_exec"); + return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + ARRAY_SIZE(param_in), param_in, 0, NULL); +} + +static int mips64_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint64_t addr, + unsigned count, uint32_t *buf) +{ + int retval = ERROR_OK; + + for (unsigned i = 0; i < count; i++) { + retval = mips64_pracc_write_u32(ejtag_info, addr + 4 * i, &buf[i]); + if (retval != ERROR_OK) + return retval; + } + return retval; +} + +static int mips64_pracc_write_u16(struct mips_ejtag *ejtag_info, uint64_t addr, + uint16_t *buf) +{ + const uint32_t code[] = { + /* move $15 to COP0 DeSave */ + MIPS64_DMTC0(15, 31, 0), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + /* sd $8, ($15) */ + MIPS64_SD(8, 0, 15), + /* sd $9, ($15) */ + MIPS64_SD(9, 0, 15), + /* load R8 @ param_in[1] = data */ + MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN) - 8), 15), + /* load R9 @ param_in[0] = address */ + MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15), + /* sh $8, 0($9) */ + MIPS64_SH(8, 0, 9), + /* ld $9, ($15) */ + MIPS64_LD(9, 0, 15), + /* ld $8, ($15) */ + MIPS64_LD(8, 0, 15), + MIPS64_SYNC, + /* b start */ + MIPS64_B(NEG16(12)), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + uint64_t param_in[2]; + param_in[0] = addr; + param_in[1] = *buf; + + LOG_DEBUG("enter mips64_pracc_exec"); + return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + ARRAY_SIZE(param_in), param_in, 0, NULL); +} + +static int mips64_pracc_write_mem16(struct mips_ejtag *ejtag_info, + uint64_t addr, unsigned count, uint16_t *buf) +{ + int retval = ERROR_OK; + + for (unsigned i = 0; i < count; i++) { + retval = mips64_pracc_write_u16(ejtag_info, addr + 2 * i, &buf[i]); + if (retval != ERROR_OK) + return retval; + } + return retval; +} + +static int mips64_pracc_write_u8(struct mips_ejtag *ejtag_info, uint64_t addr, + uint8_t *buf) +{ + const uint32_t code[] = { + /* move $15 to COP0 DeSave */ + MIPS64_DMTC0(15, 31, 0), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + /* sd $8, ($15) */ + MIPS64_SD(8, 0, 15), + /* sd $9, ($15) */ + MIPS64_SD(9, 0, 15), + /* load R8 @ param_in[1] = data */ + MIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN) - 8), 15), + /* load R9 @ param_in[0] = address */ + MIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15), + /* sh $8, 0($9) */ + MIPS64_SB(8, 0, 9), + /* ld $9, ($15) */ + MIPS64_LD(9, 0, 15), + /* ld $8, ($15) */ + MIPS64_LD(8, 0, 15), + MIPS64_SYNC, + /* b start */ + MIPS64_B(NEG16(12)), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + /* TODO remove array */ + uint64_t param_in[2]; + param_in[0] = addr; + param_in[1] = *buf; + + LOG_DEBUG("enter mips64_pracc_exec"); + return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + ARRAY_SIZE(param_in), param_in, 0, NULL); +} + +static int mips64_pracc_write_mem8(struct mips_ejtag *ejtag_info, + uint64_t addr, unsigned count, uint8_t *buf) +{ + int retval = ERROR_OK; + + for (unsigned i = 0; i < count; i++) { + retval = mips64_pracc_write_u8(ejtag_info, addr + i, &buf[i]); + if (retval != ERROR_OK) + return retval; + } + return retval; +} + +int mips64_pracc_write_mem(struct mips_ejtag *ejtag_info, + uint64_t addr, unsigned size, + unsigned count, void *buf) +{ + switch (size) { + case 1: + return mips64_pracc_write_mem8(ejtag_info, addr, count, buf); + case 2: + return mips64_pracc_write_mem16(ejtag_info, addr, count, buf); + case 4: + return mips64_pracc_write_mem32(ejtag_info, addr, count, buf); + case 8: + return mips64_pracc_write_mem64(ejtag_info, addr, count, buf); + } + return ERROR_FAIL; +} + +int mips64_pracc_write_regs(struct mips_ejtag *ejtag_info, uint64_t *regs) +{ + const uint32_t code[] = { + /* move $2 to COP0 DeSave */ + MIPS64_DMTC0(2, 31, 0), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_IN)), + MIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_IN)), + /* sd $0, 0*8($2) */ + MIPS64_LD(1, 1*8, 2), + /* sd $1, 1*8($2) */ + MIPS64_LD(15, 15*8, 2), + /* sd $11, ($15) */ + MIPS64_DMFC0(2, 31, 0), + MIPS64_DMTC0(15, 31, 0), + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + MIPS64_SD(1, 0, 15), + /* $11 = MIPS64_PRACC_PARAM_OUT */ + MIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_IN)), + MIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_IN)), + MIPS64_LD(3, 3*8, 1), + MIPS64_LD(4, 4*8, 1), + MIPS64_LD(5, 5*8, 1), + MIPS64_LD(6, 6*8, 1), + MIPS64_LD(7, 7*8, 1), + MIPS64_LD(8, 8*8, 1), + MIPS64_LD(9, 9*8, 1), + MIPS64_LD(10, 10*8, 1), + MIPS64_LD(11, 11*8, 1), + MIPS64_LD(12, 12*8, 1), + MIPS64_LD(13, 13*8, 1), + MIPS64_LD(14, 14*8, 1), + MIPS64_LD(16, 16*8, 1), + MIPS64_LD(17, 17*8, 1), + MIPS64_LD(18, 18*8, 1), + MIPS64_LD(19, 19*8, 1), + MIPS64_LD(20, 20*8, 1), + MIPS64_LD(21, 21*8, 1), + MIPS64_LD(22, 22*8, 1), + MIPS64_LD(23, 23*8, 1), + MIPS64_LD(24, 24*8, 1), + MIPS64_LD(25, 25*8, 1), + MIPS64_LD(26, 26*8, 1), + MIPS64_LD(27, 27*8, 1), + MIPS64_LD(28, 28*8, 1), + MIPS64_LD(29, 29*8, 1), + MIPS64_LD(30, 30*8, 1), + MIPS64_LD(31, 31*8, 1), + MIPS64_LD(2, 32*8, 1), + MIPS64_MTLO(2), + MIPS64_LD(2, 33*8, 1), + MIPS64_MTHI(2), + MIPS64_LD(2, MIPS64_NUM_CORE_REGS * 8, 1), + MIPS64_DMTC0(2, MIPS64_C0_DEPC, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 2) * 8, 1), + MIPS64_DMTC0(2, MIPS64_C0_ENTRYLO0, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 3) * 8, 1), + MIPS64_DMTC0(2, MIPS64_C0_ENTRYLO1, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 4) * 8, 1), + MIPS64_DMTC0(2, MIPS64_C0_CONTEXT, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 5) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_PAGEMASK, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 6) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_WIRED, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 8) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_COUNT, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 9) * 8, 1), + MIPS64_DMTC0(2, MIPS64_C0_ENTRYHI, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 10) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_COMPARE, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 11) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_STATUS, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 12) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_CAUSE, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 13) * 8, 1), + MIPS64_DMTC0(2, MIPS64_C0_EPC, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 15) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_CONFIG, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 16) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_LLA, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 21) * 8, 1), + MIPS64_DMTC0(2, MIPS64_C0_XCONTEXT, 1), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 22) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_MEMCTRL, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 24) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 25) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 1), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 26) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 2), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 27) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 3), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 28) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_ECC, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 29) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_CACHERR, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 30) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_TAGLO, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 31) * 8, 1), + MIPS64_MTC0(2, MIPS64_C0_TAGHI, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 32) * 8, 1), + MIPS64_DMTC0(2, MIPS64_C0_DATAHI, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 33) * 8, 1), + MIPS64_DMTC0(2, MIPS64_C0_EEPC, 0), + /* check if FPU is enabled, */ + MIPS64_MFC0(2, MIPS64_C0_STATUS, 0), + MIPS64_SRL(2, 2, 29), + MIPS64_ANDI(2, 2, 1), + /* skip FPU registers restoration if not */ + MIPS64_BEQ(0, 2, 77), + MIPS64_NOP, + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 33) * 8, 1), + MIPS64_CTC1(2, MIPS64_C1_FIR, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 32) * 8, 1), + MIPS64_CTC1(2, MIPS64_C1_FCSR, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 34) * 8, 1), + MIPS64_CTC1(2, MIPS64_C1_FCONFIG, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 35) * 8, 1), + MIPS64_CTC1(2, MIPS64_C1_FCCR, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 36) * 8, 1), + MIPS64_CTC1(2, MIPS64_C1_FEXR, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 37) * 8, 1), + MIPS64_CTC1(2, MIPS64_C1_FENR, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 0) * 8, 1), + MIPS64_DMTC1(2, 0, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 1) * 8, 1), + MIPS64_DMTC1(2, 1, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 2) * 8, 1), + MIPS64_DMTC1(2, 2, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 3) * 8, 1), + MIPS64_DMTC1(2, 3, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 4) * 8, 1), + MIPS64_DMTC1(2, 4, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 5) * 8, 1), + MIPS64_DMTC1(2, 5, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 6) * 8, 1), + MIPS64_DMTC1(2, 6, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 7) * 8, 1), + MIPS64_DMTC1(2, 7, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 8) * 8, 1), + MIPS64_DMTC1(2, 8, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 9) * 8, 1), + MIPS64_DMTC1(2, 9, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 10) * 8, 1), + MIPS64_DMTC1(2, 10, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 11) * 8, 1), + MIPS64_DMTC1(2, 11, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 12) * 8, 1), + MIPS64_DMTC1(2, 12, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 13) * 8, 1), + MIPS64_DMTC1(2, 13, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 14) * 8, 1), + MIPS64_DMTC1(2, 14, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 15) * 8, 1), + MIPS64_DMTC1(2, 15, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 16) * 8, 1), + MIPS64_DMTC1(2, 16, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 17) * 8, 1), + MIPS64_DMTC1(2, 17, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 18) * 8, 1), + MIPS64_DMTC1(2, 18, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 19) * 8, 1), + MIPS64_DMTC1(2, 19, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 20) * 8, 1), + MIPS64_DMTC1(2, 20, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 21) * 8, 1), + MIPS64_DMTC1(2, 21, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 22) * 8, 1), + MIPS64_DMTC1(2, 22, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 23) * 8, 1), + MIPS64_DMTC1(2, 23, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 24) * 8, 1), + MIPS64_DMTC1(2, 24, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 25) * 8, 1), + MIPS64_DMTC1(2, 25, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 26) * 8, 1), + MIPS64_DMTC1(2, 26, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 27) * 8, 1), + MIPS64_DMTC1(2, 27, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 28) * 8, 1), + MIPS64_DMTC1(2, 28, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 29) * 8, 1), + MIPS64_DMTC1(2, 29, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 30) * 8, 1), + MIPS64_DMTC1(2, 30, 0), + MIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 31) * 8, 1), + MIPS64_DMTC1(2, 31, 0), + MIPS64_LD(2, 2 * 8, 1), + MIPS64_LD(1, 0, 15), + MIPS64_SYNC, + /* b start */ + MIPS64_B(NEG16(181)), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + LOG_DEBUG("enter mips64_pracc_exec"); + return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + MIPS64_NUM_REGS, regs, 0, NULL); +} + +int mips64_pracc_read_regs(struct mips_ejtag *ejtag_info, uint64_t *regs) +{ + const uint32_t code[] = { + /* move $2 to COP0 DeSave */ + MIPS64_DMTC0(2, 31, 0), + /* $2 = MIPS64_PRACC_PARAM_OUT */ + MIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_OUT)), + MIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_OUT)), + /* sd $0, 0*8($2) */ + MIPS64_SD(0, 0*8, 2), + /* sd $1, 1*8($2) */ + MIPS64_SD(1, 1*8, 2), + /* sd $15, 15*8($2) */ + MIPS64_SD(15, 15*8, 2), + /* move COP0 DeSave to $2 */ + MIPS64_DMFC0(2, 31, 0), + /* move $15 to COP0 DeSave */ + MIPS64_DMTC0(15, 31, 0), + /* $15 = MIPS64_PRACC_STACK */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + /* sd $1, ($15) */ + MIPS64_SD(1, 0, 15), + /* sd $2, ($15) */ + MIPS64_SD(2, 0, 15), + /* $1 = MIPS64_PRACC_PARAM_OUT */ + MIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_OUT)), + MIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_OUT)), + MIPS64_SD(2, 2 * 8, 1), + MIPS64_SD(3, 3 * 8, 1), + MIPS64_SD(4, 4 * 8, 1), + MIPS64_SD(5, 5 * 8, 1), + MIPS64_SD(6, 6 * 8, 1), + MIPS64_SD(7, 7 * 8, 1), + MIPS64_SD(8, 8 * 8, 1), + MIPS64_SD(9, 9 * 8, 1), + MIPS64_SD(10, 10 * 8, 1), + MIPS64_SD(11, 11 * 8, 1), + MIPS64_SD(12, 12 * 8, 1), + MIPS64_SD(13, 13 * 8, 1), + MIPS64_SD(14, 14 * 8, 1), + MIPS64_SD(16, 16 * 8, 1), + MIPS64_SD(17, 17 * 8, 1), + MIPS64_SD(18, 18 * 8, 1), + MIPS64_SD(19, 19 * 8, 1), + MIPS64_SD(20, 20 * 8, 1), + MIPS64_SD(21, 21 * 8, 1), + MIPS64_SD(22, 22 * 8, 1), + MIPS64_SD(23, 23 * 8, 1), + MIPS64_SD(24, 24 * 8, 1), + MIPS64_SD(25, 25 * 8, 1), + MIPS64_SD(26, 26 * 8, 1), + MIPS64_SD(27, 27 * 8, 1), + MIPS64_SD(28, 28 * 8, 1), + MIPS64_SD(29, 29 * 8, 1), + MIPS64_SD(30, 30 * 8, 1), + MIPS64_SD(31, 31 * 8, 1), + MIPS64_MFLO(2), + MIPS64_SD(2, 32 * 8, 1), + MIPS64_MFHI(2), + MIPS64_SD(2, 33 * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_DEPC, 0), + MIPS64_SD(2, MIPS64_NUM_CORE_REGS * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_RANDOM, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 1) * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_ENTRYLO0, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 2) * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_ENTRYLO1, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 3) * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_CONTEXT, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 4) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_PAGEMASK, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 5) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_WIRED, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 6) * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_BADVADDR, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 7) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_COUNT, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 8) * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_ENTRYHI, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 9) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_COMPARE, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 10) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_STATUS, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 11) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_CAUSE, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 12) * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_EPC, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 13) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_PRID, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 14) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_CONFIG, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 15) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_LLA, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 16) * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_XCONTEXT, 1), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 21) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_MEMCTRL, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 22) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_DEBUG, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 23) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 24) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 1), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 25) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 2), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 26) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 3), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 27) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_ECC, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 28) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_CACHERR, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 29) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_TAGLO, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 30) * 8, 1), + MIPS64_MFC0(2, MIPS64_C0_TAGHI, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 31) * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_DATAHI, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 32) * 8, 1), + MIPS64_DMFC0(2, MIPS64_C0_EEPC, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 33) * 8, 1), + /* check if FPU is enabled, */ + MIPS64_MFC0(2, MIPS64_C0_STATUS, 0), + MIPS64_SRL(2, 2, 29), + MIPS64_ANDI(2, 2, 1), + /* skip FPU registers dump if not */ + MIPS64_BEQ(0, 2, 77), + MIPS64_NOP, + MIPS64_CFC1(2, MIPS64_C1_FIR, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 33) * 8, 1), + MIPS64_CFC1(2, MIPS64_C1_FCSR, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 32) * 8, 1), + MIPS64_CFC1(2, MIPS64_C1_FCONFIG, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 34) * 8, 1), + MIPS64_CFC1(2, MIPS64_C1_FCCR, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 35) * 8, 1), + MIPS64_CFC1(2, MIPS64_C1_FEXR, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 36) * 8, 1), + MIPS64_CFC1(2, MIPS64_C1_FENR, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 37) * 8, 1), + MIPS64_DMFC1(2, 0, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 0) * 8, 1), + MIPS64_DMFC1(2, 1, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 1) * 8, 1), + MIPS64_DMFC1(2, 2, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 2) * 8, 1), + MIPS64_DMFC1(2, 3, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 3) * 8, 1), + MIPS64_DMFC1(2, 4, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 4) * 8, 1), + MIPS64_DMFC1(2, 5, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 5) * 8, 1), + MIPS64_DMFC1(2, 6, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 6) * 8, 1), + MIPS64_DMFC1(2, 7, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 7) * 8, 1), + MIPS64_DMFC1(2, 8, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 8) * 8, 1), + MIPS64_DMFC1(2, 9, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 9) * 8, 1), + MIPS64_DMFC1(2, 10, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 10) * 8, 1), + MIPS64_DMFC1(2, 11, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 11) * 8, 1), + MIPS64_DMFC1(2, 12, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 12) * 8, 1), + MIPS64_DMFC1(2, 13, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 13) * 8, 1), + MIPS64_DMFC1(2, 14, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 14) * 8, 1), + MIPS64_DMFC1(2, 15, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 15) * 8, 1), + MIPS64_DMFC1(2, 16, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 16) * 8, 1), + MIPS64_DMFC1(2, 17, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 17) * 8, 1), + MIPS64_DMFC1(2, 18, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 18) * 8, 1), + MIPS64_DMFC1(2, 19, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 19) * 8, 1), + MIPS64_DMFC1(2, 20, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 20) * 8, 1), + MIPS64_DMFC1(2, 21, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 21) * 8, 1), + MIPS64_DMFC1(2, 22, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 22) * 8, 1), + MIPS64_DMFC1(2, 23, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 23) * 8, 1), + MIPS64_DMFC1(2, 24, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 24) * 8, 1), + MIPS64_DMFC1(2, 25, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 25) * 8, 1), + MIPS64_DMFC1(2, 26, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 26) * 8, 1), + MIPS64_DMFC1(2, 27, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 27) * 8, 1), + MIPS64_DMFC1(2, 28, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 28) * 8, 1), + MIPS64_DMFC1(2, 29, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 29) * 8, 1), + MIPS64_DMFC1(2, 30, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 30) * 8, 1), + MIPS64_DMFC1(2, 31, 0), + MIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 31) * 8, 1), + MIPS64_LD(2, 0, 15), + MIPS64_LD(1, 0, 15), + MIPS64_SYNC, + /* b start */ + MIPS64_B(NEG16(192)), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + LOG_DEBUG("enter mips64_pracc_exec"); + return mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, + 0, NULL, MIPS64_NUM_REGS, regs); +} + +/* fastdata upload/download requires an initialized working area + * to load the download code; it should not be called otherwise + * fetch order from the fastdata area + * 1. start addr + * 2. end addr + * 3. data ... + */ +int mips64_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, + struct working_area *source, + bool write_t, uint64_t addr, + unsigned count, uint64_t *buf) +{ + uint32_t handler_code[] = { + /* caution when editing, table is modified below */ + /* r15 points to the start of this code */ + MIPS64_SD(8, MIPS64_FASTDATA_HANDLER_SIZE - 8, 15), + MIPS64_SD(9, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 2, 15), + MIPS64_SD(10, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 3, 15), + MIPS64_SD(11, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 4, 15), + /* start of fastdata area in t0 */ + MIPS64_LUI(8, UPPER16(MIPS64_PRACC_FASTDATA_AREA)), + MIPS64_ORI(8, 8, LOWER16(MIPS64_PRACC_FASTDATA_AREA)), + /* start addr in t1 */ + MIPS64_LD(9, 0, 8), + /* end addr to t2 */ + MIPS64_LD(10, 0, 8), + + /* loop: */ + /* lw t3,[t8 | r9] */ + /* 8 */ MIPS64_LD(11, 0, 0), + /* sw t3,[r9 | r8] */ + /* 9 */ MIPS64_SD(11, 0, 0), + /* bne $t2,t1,loop */ + MIPS64_BNE(10, 9, NEG16(3)), + /* addi t1,t1,4 */ + MIPS64_DADDIU(9, 9, 8), + + MIPS64_LD(8, MIPS64_FASTDATA_HANDLER_SIZE - 8, 15), + MIPS64_LD(9, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 2, 15), + MIPS64_LD(10, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 3, 15), + MIPS64_LD(11, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 4, 15), + + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_TEXT)), + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_TEXT)), + /* jr start */ + MIPS64_JR(15), + /* move COP0 DeSave to $15 */ + MIPS64_DMFC0(15, 31, 0), + }; + + uint32_t jmp_code[] = { + /* addr of working area added below */ + /* 0 */ MIPS64_LUI(15, 0), + /* addr of working area added below */ + /* 1 */ MIPS64_ORI(15, 15, 0), + /* jump to ram program */ + MIPS64_JR(15), + MIPS64_NOP, + }; + + int retval; + unsigned i; + uint32_t ejtag_ctrl, address32; + uint64_t address, val; + + if (source->size < MIPS64_FASTDATA_HANDLER_SIZE) + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + + if (write_t) { + /* load data from probe at fastdata area */ + handler_code[8] = MIPS64_LD(11, 0, 8); + /* store data to RAM @ r9 */ + handler_code[9] = MIPS64_SD(11, 0, 9); + } else { + /* load data from RAM @ r9 */ + handler_code[8] = MIPS64_LD(11, 0, 9); + /* store data to probe at fastdata area */ + handler_code[9] = MIPS64_SD(11, 0, 8); + } + + /* write program into RAM */ + if (write_t != ejtag_info->fast_access_save) { + mips64_pracc_write_mem(ejtag_info, source->address, 4, + ARRAY_SIZE(handler_code), handler_code); + /* save previous operation to speed to any consecutive read/writes */ + ejtag_info->fast_access_save = write_t; + } + + LOG_DEBUG("%s using " TARGET_ADDR_FMT " for write handler", __func__, + source->address); + LOG_DEBUG("daddiu: %08x", handler_code[11]); + + jmp_code[0] |= UPPER16(source->address); + jmp_code[1] |= LOWER16(source->address); + mips64_pracc_exec(ejtag_info, + ARRAY_SIZE(jmp_code), jmp_code, + 0, NULL, 0, NULL); + + /* next fetch to dmseg should be in FASTDATA_AREA, check */ + address = 0; + + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); + retval = mips_ejtag_drscan_32(ejtag_info, &address32); + if (retval != ERROR_OK) + return retval; + address = 0xffffffffff200000ull | address32; + if ((address & ~7ull) != MIPS64_PRACC_FASTDATA_AREA) { + LOG_ERROR("! @MIPS64_PRACC_FASTDATA_AREA (" TARGET_ADDR_FMT ")", address); + return ERROR_FAIL; + } + /* Send the load start address */ + val = addr; + LOG_DEBUG("start: " TARGET_ADDR_FMT, val); + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA); + mips64_ejtag_fastdata_scan(ejtag_info, 1, &val); + + retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl); + if (retval != ERROR_OK) + return retval; + + /* Send the load end address */ + val = addr + (count - 1) * 8; + LOG_DEBUG("stop: " TARGET_ADDR_FMT, val); + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA); + mips64_ejtag_fastdata_scan(ejtag_info, 1, &val); + + /* like in legacy code */ + unsigned num_clocks = 0; + if (ejtag_info->mode != 0) + num_clocks = ((uint64_t)(ejtag_info->scan_delay) * jtag_get_speed_khz() + 500000) / 1000000; + LOG_DEBUG("num_clocks=%d", num_clocks); + for (i = 0; i < count; i++) { + jtag_add_clocks(num_clocks); + retval = mips64_ejtag_fastdata_scan(ejtag_info, write_t, buf++); + if (retval != ERROR_OK) { + LOG_ERROR("mips64_ejtag_fastdata_scan failed"); + return retval; + } + } + + retval = jtag_execute_queue(); + if (retval != ERROR_OK) { + LOG_ERROR("jtag_execute_queue failed"); + return retval; + } + + retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl); + if (retval != ERROR_OK) { + LOG_ERROR("wait_for_pracc_rw failed"); + return retval; + } + + address = 0; + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS); + retval = mips_ejtag_drscan_32(ejtag_info, &address32); + if (retval != ERROR_OK) { + LOG_ERROR("mips_ejtag_drscan_32 failed"); + return retval; + } + + address = 0xffffffffff200000ull | address32; + if ((address & ~7ull) != MIPS64_PRACC_TEXT) + LOG_ERROR("mini program did not return to start"); + + return retval; +} + +#endif /* BUILD_TARGET64 */ diff --git a/src/target/mips64_pracc.h b/src/target/mips64_pracc.h new file mode 100644 index 000000000..65ff6e6ac --- /dev/null +++ b/src/target/mips64_pracc.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Support for processors implementing MIPS64 instruction set + * + * Copyright (C) 2014 by Andrey Sidorov + * Copyright (C) 2014 by Aleksey Kuleshov + * Copyright (C) 2014-2019 by Peter Mamonov + * + * Based on the work of: + * Copyright (C) 2008 by Spencer Oliver + * Copyright (C) 2008 by David T.L. Wong + * Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev + */ + +#ifndef OPENOCD_TARGET_MIPS64_PRACC_H +#define OPENOCD_TARGET_MIPS64_PRACC_H + +#include "mips_ejtag.h" + +#define MIPS64_PRACC_TEXT 0xffffffffFF200200ull + +#define MIPS64_PRACC_STACK 0xffffffffFF204000ull +#define MIPS64_PRACC_PARAM_IN 0xffffffffFF201000ull +#define MIPS64_PRACC_PARAM_IN_SIZE 0x1000 +#define MIPS64_PRACC_PARAM_OUT (MIPS64_PRACC_PARAM_IN + MIPS64_PRACC_PARAM_IN_SIZE) +#define MIPS64_PRACC_PARAM_OUT_SIZE 0x1000 + +#undef UPPER16 +#undef LOWER16 +#define UPPER16(v) ((uint32_t)((v >> 16) & 0xFFFF)) +#define LOWER16(v) ((uint32_t)(v & 0xFFFF)) +#define MIPS64_PRACC_FASTDATA_AREA 0xffffffffFF200000 +#define MIPS64_PRACC_FASTDATA_SIZE 16 +#define MIPS64_FASTDATA_HANDLER_SIZE 0x80 + +/* FIXME: 16-bit NEG */ +#undef NEG16 +#define NEG16(v) ((uint32_t)(((~(v)) + 1) & 0xFFFF)) + +#define MIPS64_PRACC_ADDR_STEP 4 +#define MIPS64_PRACC_DATA_STEP 8 + +int mips64_pracc_read_mem(struct mips_ejtag *ejtag_info, uint64_t addr, unsigned size, unsigned count, void *buf); +int mips64_pracc_write_mem(struct mips_ejtag *ejtag_info, uint64_t addr, unsigned size, unsigned count, void *buf); + +int mips64_pracc_read_regs(struct mips_ejtag *ejtag_info, uint64_t *regs); +int mips64_pracc_write_regs(struct mips_ejtag *ejtag_info, uint64_t *regs); + +int mips64_pracc_exec(struct mips_ejtag *ejtag_info, + unsigned code_len, const uint32_t *code, + unsigned num_param_in, uint64_t *param_in, + unsigned num_param_out, uint64_t *param_out); + +int mips64_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, + struct working_area *source, + bool write_t, uint64_t addr, + unsigned count, uint64_t *buf); + +#endif /* OPENOCD_TARGET_MIPS64_PRACC_H */ diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c index 03a09529c..0b8122e1c 100644 --- a/src/target/mips_ejtag.c +++ b/src/target/mips_ejtag.c @@ -28,6 +28,11 @@ #include "mips_ejtag.h" #include "mips32_dmaacc.h" +#if BUILD_TARGET64 == 1 +#include "mips64.h" +#include "mips64_pracc.h" +#endif + void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr) { assert(ejtag_info->tap != NULL); @@ -87,6 +92,36 @@ void mips_ejtag_add_scan_96(struct mips_ejtag *ejtag_info, uint32_t ctrl, uint32 keep_alive(); } +int mips_ejtag_drscan_64(struct mips_ejtag *ejtag_info, uint64_t *data) +{ + struct jtag_tap *tap; + tap = ejtag_info->tap; + + if (tap == NULL) + return ERROR_FAIL; + struct scan_field field; + uint8_t t[8], r[8]; + int retval; + + field.num_bits = 64; + field.out_value = t; + buf_set_u64(t, 0, field.num_bits, *data); + field.in_value = r; + + jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); + retval = jtag_execute_queue(); + if (retval != ERROR_OK) { + LOG_ERROR("register read failed"); + return retval; + } + + *data = buf_get_u64(field.in_value, 0, 64); + + keep_alive(); + + return ERROR_OK; +} + void mips_ejtag_drscan_32_queued(struct mips_ejtag *ejtag_info, uint32_t data_out, uint8_t *data_in) { assert(ejtag_info->tap != NULL); @@ -422,3 +457,112 @@ int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_ return ERROR_OK; } + +#if BUILD_TARGET64 == 1 + +int mips64_ejtag_config_step(struct mips_ejtag *ejtag_info, bool enable_step) +{ + const uint32_t code_enable[] = { + MIPS64_MTC0(1, 31, 0), /* move $1 to COP0 DeSave */ + MIPS64_MFC0(1, 23, 0), /* move COP0 Debug to $1 */ + MIPS64_ORI(1, 1, 0x0100), /* set SSt bit in debug reg */ + MIPS64_MTC0(1, 23, 0), /* move $1 to COP0 Debug */ + MIPS64_B(NEG16(5)), + MIPS64_MFC0(1, 31, 0), /* move COP0 DeSave to $1 */ + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + + const uint32_t code_disable[] = { + MIPS64_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ + MIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)), /* $15 = MIPS64_PRACC_STACK */ + MIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)), + MIPS64_SD(1, 0, 15), /* sw $1,($15) */ + MIPS64_SD(2, 0, 15), /* sw $2,($15) */ + MIPS64_MFC0(1, 23, 0), /* move COP0 Debug to $1 */ + MIPS64_LUI(2, 0xFFFF), /* $2 = 0xfffffeff */ + MIPS64_ORI(2, 2, 0xFEFF), + MIPS64_AND(1, 1, 2), + MIPS64_MTC0(1, 23, 0), /* move $1 to COP0 Debug */ + MIPS64_LD(2, 0, 15), + MIPS64_LD(1, 0, 15), + MIPS64_SYNC, + MIPS64_B(NEG16(14)), + MIPS64_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */ + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + const uint32_t *code = enable_step ? code_enable : code_disable; + unsigned code_len = enable_step ? ARRAY_SIZE(code_enable) : + ARRAY_SIZE(code_disable); + + return mips64_pracc_exec(ejtag_info, + code_len, code, 0, NULL, 0, NULL); +} + +int mips64_ejtag_exit_debug(struct mips_ejtag *ejtag_info) +{ + const uint32_t code[] = { + MIPS64_DRET, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + MIPS64_NOP, + }; + LOG_DEBUG("enter mips64_pracc_exec"); + return mips64_pracc_exec(ejtag_info, + ARRAY_SIZE(code), code, 0, NULL, 0, NULL); +} + +int mips64_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, bool write_t, uint64_t *data) +{ + struct jtag_tap *tap; + + tap = ejtag_info->tap; + assert(tap != NULL); + + struct scan_field fields[2]; + uint8_t spracc = 0; + uint8_t t[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + + /* fastdata 1-bit register */ + fields[0].num_bits = 1; + fields[0].out_value = &spracc; + fields[0].in_value = NULL; + + /* processor access data register 64 bit */ + fields[1].num_bits = 64; + fields[1].out_value = t; + + if (write_t) { + fields[1].in_value = NULL; + buf_set_u64(t, 0, 64, *data); + } else + fields[1].in_value = (uint8_t *) data; + + jtag_add_dr_scan(tap, 2, fields, TAP_IDLE); + + if (!write_t && data) + jtag_add_callback(mips_le_to_h_u64, + (jtag_callback_data_t) data); + keep_alive(); + + return ERROR_OK; +} + +#endif /* BUILD_TARGET64 */ diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h index c64e858a3..cfba0ab56 100644 --- a/src/target/mips_ejtag.h +++ b/src/target/mips_ejtag.h @@ -182,6 +182,20 @@ #define EJTAG_VERSION_41 4 #define EJTAG_VERSION_51 5 +/* + * Additional defines for MIPS64 EJTAG + */ +#define EJTAG64_DCR 0xFFFFFFFFFF300000ull +#define EJTAG64_DCR_ENM (1llu << 29) +#define EJTAG64_DCR_DB (1llu << 17) +#define EJTAG64_DCR_IB (1llu << 16) +#define EJTAG64_DCR_INTE (1llu << 4) +#define EJTAG64_DCR_MP (1llu << 2) +#define EJTAG64_V25_DBA0 0xFFFFFFFFFF302100ull +#define EJTAG64_V25_DBS 0xFFFFFFFFFF302000ull +#define EJTAG64_V25_IBA0 0xFFFFFFFFFF301100ull +#define EJTAG64_V25_IBS 0xFFFFFFFFFF301000ull + struct mips_ejtag { struct jtag_tap *tap; uint32_t impcode; @@ -224,17 +238,21 @@ struct mips_ejtag { void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr); int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info); int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info); +int mips64_ejtag_exit_debug(struct mips_ejtag *ejtag_info); int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info); void mips_ejtag_add_scan_96(struct mips_ejtag *ejtag_info, uint32_t ctrl, uint32_t data, uint8_t *in_scan_buf); +int mips_ejtag_drscan_64(struct mips_ejtag *ejtag_info, uint64_t *data); void mips_ejtag_drscan_32_out(struct mips_ejtag *ejtag_info, uint32_t data); int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data); void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data); int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint8_t *data); int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data); +int mips64_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, bool write_t, uint64_t *data); int mips_ejtag_init(struct mips_ejtag *ejtag_info); int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step); +int mips64_ejtag_config_step(struct mips_ejtag *ejtag_info, bool enable_step); static inline void mips_le_to_h_u32(jtag_callback_data_t arg) { @@ -242,4 +260,10 @@ static inline void mips_le_to_h_u32(jtag_callback_data_t arg) *((uint32_t *)arg) = le_to_h_u32(in); } +static inline void mips_le_to_h_u64(jtag_callback_data_t arg) +{ + uint8_t *in = (uint8_t *)arg; + *((uint64_t *)arg) = le_to_h_u64(in); +} + #endif /* OPENOCD_TARGET_MIPS_EJTAG_H */ From 80f1a92bd7989bfdd8b7f00d947149b77407e15c Mon Sep 17 00:00:00 2001 From: Peter Mamonov Date: Tue, 23 Sep 2014 12:51:05 +0400 Subject: [PATCH 038/354] mips64: Add generic mips64 target support Change-Id: I2bdd2573f23e65652686d18031698f423eec77c0 Signed-off-by: Konstantin Kostyukhin Signed-off-by: Aleksey Kuleshov Signed-off-by: Peter Mamonov Signed-off-by: Oleksij Rempel CC: Dongxue Zhang CC: Paul Fertser CC: Salvador Arroyo CC: Spencer Oliver Reviewed-on: http://openocd.zylin.com/2322 Tested-by: jenkins Reviewed-by: Paul Fertser --- src/target/Makefile.am | 2 + src/target/mips_mips64.c | 1197 ++++++++++++++++++++++++++++++++++++++ src/target/mips_mips64.h | 24 + src/target/target.c | 2 + 4 files changed, 1225 insertions(+) create mode 100644 src/target/mips_mips64.c create mode 100644 src/target/mips_mips64.h diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 2a7cc4b3b..08a4b961f 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -125,6 +125,7 @@ MIPS64_SRC = \ %D%/mips64.c \ %D%/mips32_pracc.c \ %D%/mips64_pracc.c \ + %D%/mips_mips64.c \ %D%/trace.c \ %D%/mips_ejtag.c @@ -203,6 +204,7 @@ ESIRISC_SRC = \ %D%/mips32.h \ %D%/mips64.h \ %D%/mips_m4k.h \ + %D%/mips_mips64.h \ %D%/mips_ejtag.h \ %D%/mips32_pracc.h \ %D%/mips32_dmaacc.h \ diff --git a/src/target/mips_mips64.c b/src/target/mips_mips64.c new file mode 100644 index 000000000..d91700dfe --- /dev/null +++ b/src/target/mips_mips64.c @@ -0,0 +1,1197 @@ +/* + * MIPS64 generic target support + * + * Copyright (C) 2014 by Andrey Sidorov + * Copyright (C) 2014 by Aleksey Kuleshov + * Copyright (C) 2014-2019 by Peter Mamonov + * + * Based on the work of: + * Copyright (C) 2008 by Spencer Oliver + * Copyright (C) 2008 by David T.L. Wong + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if BUILD_TARGET64 == 1 + +#include "breakpoints.h" +#include "mips32.h" +#include "mips64.h" +#include "mips_mips64.h" +#include "target_type.h" +#include "register.h" + +static int mips_mips64_unset_breakpoint(struct target *target, + struct breakpoint *breakpoint); + +static uint64_t mips64_extend_sign(uint64_t addr) +{ + if (addr >> 32) + return addr; + if (addr >> 31) + return addr | (ULLONG_MAX << 32); + return addr; +} + +static int mips_mips64_examine_debug_reason(struct target *target) +{ + if ((target->debug_reason != DBG_REASON_DBGRQ) + && (target->debug_reason != DBG_REASON_SINGLESTEP)) + target->debug_reason = DBG_REASON_BREAKPOINT; + + return ERROR_OK; +} + +static int mips_mips64_debug_entry(struct target *target) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + struct reg *pc = &mips64->core_cache->reg_list[MIPS64_PC]; + + mips64_save_context(target); + + /* make sure stepping disabled, SSt bit in CP0 debug register cleared */ + mips64_ejtag_config_step(ejtag_info, 0); + + /* make sure break unit configured */ + mips64_configure_break_unit(target); + + /* attempt to find halt reason */ + mips_mips64_examine_debug_reason(target); + + LOG_DEBUG("entered debug state at PC 0x%" PRIx64 ", target->state: %s", + *(uint64_t *)pc->value, target_state_name(target)); + + return ERROR_OK; +} + +static int mips_mips64_poll(struct target *target) +{ + int retval; + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl; + + /* read ejtag control reg */ + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); + mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); + + /* clear this bit before handling polling + * as after reset registers will read zero */ + if (ejtag_ctrl & EJTAG_CTRL_ROCC) { + /* we have detected a reset, clear flag + * otherwise ejtag will not work */ + ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC; + + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); + mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); + LOG_DEBUG("Reset Detected"); + } + + /* check for processor halted */ + if (ejtag_ctrl & EJTAG_CTRL_BRKST) { + if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { + target->state = TARGET_HALTED; + retval = mips_mips64_debug_entry(target); + if (retval != ERROR_OK) + return retval; + target_call_event_callbacks(target, TARGET_EVENT_HALTED); + } else if (target->state == TARGET_DEBUG_RUNNING) { + target->state = TARGET_HALTED; + retval = mips_mips64_debug_entry(target); + if (retval != ERROR_OK) + return retval; + + target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); + } + } else { + target->state = TARGET_RUNNING; + } + + return ERROR_OK; +} + +static int mips_mips64_halt(struct target *target) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + + LOG_DEBUG("target->state: %s", + target_state_name(target)); + + if (target->state == TARGET_HALTED) { + LOG_DEBUG("target was already halted"); + return ERROR_OK; + } + + if (target->state == TARGET_UNKNOWN) + LOG_WARNING("target was in unknown state when halt was requested"); + + if (target->state == TARGET_RESET) { + if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) { + LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); + return ERROR_TARGET_FAILURE; + } else { + /* we came here in a reset_halt or reset_init sequence + * debug entry was already prepared in mips64_prepare_reset_halt() + */ + target->debug_reason = DBG_REASON_DBGRQ; + + return ERROR_OK; + } + } + + /* break processor */ + mips_ejtag_enter_debug(ejtag_info); + + target->debug_reason = DBG_REASON_DBGRQ; + + return ERROR_OK; +} + +static int mips_mips64_assert_reset(struct target *target) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + int retval; + + LOG_DEBUG("target->state: %s", + target_state_name(target)); + + enum reset_types jtag_reset_config = jtag_get_reset_config(); + if (!(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("Can't assert SRST"); + return ERROR_FAIL; + } + + if (target->reset_halt) + /* use hardware to catch reset */ + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT); + else + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT); + + /* here we should issue a srst only, but we may have to assert trst as well */ + if (jtag_reset_config & RESET_SRST_PULLS_TRST) + jtag_add_reset(1, 1); + else + jtag_add_reset(0, 1); + + target->state = TARGET_RESET; + jtag_add_sleep(5000); + + retval = mips64_invalidate_core_regs(target); + if (retval != ERROR_OK) + return retval; + + if (target->reset_halt) { + retval = target_halt(target); + if (retval != ERROR_OK) + return retval; + } + + return ERROR_OK; +} + +static int mips_mips64_deassert_reset(struct target *target) +{ + LOG_DEBUG("target->state: %s", + target_state_name(target)); + + /* deassert reset lines */ + jtag_add_reset(0, 0); + + return ERROR_OK; +} + +static int mips_mips64_soft_reset_halt(struct target *target) +{ + /* TODO */ + return ERROR_OK; +} + +static int mips_mips64_single_step_core(struct target *target) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + int retval; + + /* configure single step mode */ + mips64_ejtag_config_step(ejtag_info, 1); + + /* disable interrupts while stepping */ + retval = mips64_enable_interrupts(target, false); + if (retval != ERROR_OK) + return retval; + + /* exit debug mode */ + retval = mips64_ejtag_exit_debug(ejtag_info); + if (retval != ERROR_OK) + return retval; + + mips_mips64_debug_entry(target); + + return ERROR_OK; +} + +/* TODO: HW breakpoints are in EJTAG spec. Should we share it for MIPS32? */ +static int mips_mips64_set_hwbp(struct target *target, struct breakpoint *bp) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips64_comparator *c, *cl = mips64->inst_break_list; + uint64_t bp_value; + int retval, bp_num = 0; + + while (cl[bp_num].used && (bp_num < mips64->num_inst_bpoints)) + bp_num++; + + if (bp_num >= mips64->num_inst_bpoints) { + LOG_DEBUG("ERROR Can not find free FP Comparator(bpid: %d)", + bp->unique_id); + LOG_WARNING("ERROR Can not find free FP Comparator"); + exit(-1); + } + + c = &cl[bp_num]; + c->used = true; + c->bp_value = bp->address; + bp_value = bp->address; + + /* Instruction Breakpoint Address n (IBAn) Register */ + retval = target_write_u64(target, c->reg_address, bp_value); + if (retval != ERROR_OK) + return retval; + + /* TODO: use defines */ + /* Instruction Breakpoint Address Mask n (IBMn) Register */ + retval = target_write_u64(target, c->reg_address + 0x08, 0); + if (retval != ERROR_OK) + return retval; + + /* Instruction Breakpoint Control n (IBCn) Register */ + retval = target_write_u64(target, c->reg_address + 0x18, 1); + if (retval != ERROR_OK) + return retval; + + LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx64 "", bp->unique_id, + bp_num, c->bp_value); + + return ERROR_OK; +} + +/* TODO: is it MIPS64 or MIPS32 instruction. If MIPS32, can it be shared with + * MIPS32 code? */ +static int mips_mips64_set_sdbbp(struct target *target, struct breakpoint *bp) +{ + uint32_t verify; + int retval; + + retval = target_read_memory(target, + bp->address, bp->length, 1, + bp->orig_instr); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u32(target, bp->address, MIPS64_SDBBP); + if (retval != ERROR_OK) + return retval; + + retval = target_read_u32(target, bp->address, &verify); + if (retval != ERROR_OK) + return retval; + + if (verify != MIPS64_SDBBP) { + LOG_ERROR("Unable to set 32bit breakpoint at address %16" PRIx64, + bp->address); + retval = ERROR_FAIL; + } + + return retval; +} + +/* TODO do MIPS64 support MIPS16 instructions? Can it be shared with MIPS32 + * code? */ +static int mips_mips16_set_sdbbp(struct target *target, struct breakpoint *bp) +{ + uint32_t isa_req = bp->length & 1; + uint16_t verify; + int retval; + + retval = target_read_memory(target, + bp->address, bp->length, 1, + bp->orig_instr); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u16(target, bp->address, MIPS16_SDBBP(isa_req)); + if (retval != ERROR_OK) + return retval; + + retval = target_read_u16(target, bp->address, &verify); + if (retval != ERROR_OK) + return retval; + + if (verify != MIPS16_SDBBP(isa_req)) { + LOG_ERROR("Unable to set 16bit breakpoint at address %16" PRIx64, + bp->address); + retval = ERROR_FAIL; + } + + return retval; +} + +static int mips_mips64_set_breakpoint(struct target *target, + struct breakpoint *bp) +{ + int retval; + + if (bp->set) { + LOG_WARNING("breakpoint already set"); + return ERROR_OK; + } + + if (bp->type == BKPT_HARD) { + retval = mips_mips64_set_hwbp(target, bp); + } else { + LOG_DEBUG("bpid: %d", bp->unique_id); + + switch (bp->length) { + case MIPS64_SDBBP_SIZE: + retval = mips_mips64_set_sdbbp(target, bp); + break; + case MIPS16_SDBBP_SIZE: + retval = mips_mips16_set_sdbbp(target, bp); + break; + default: + retval = ERROR_FAIL; + } + } + + if (retval != ERROR_OK) { + LOG_ERROR("can't unset breakpoint. Some thing wrong happened"); + return retval; + } + + bp->set = true; + + return ERROR_OK; +} + +static int mips_mips64_enable_breakpoints(struct target *target) +{ + struct breakpoint *bp = target->breakpoints; + int retval = ERROR_OK; + + /* set any pending breakpoints */ + while (bp) { + if (!bp->set) { + retval = mips_mips64_set_breakpoint(target, bp); + if (retval != ERROR_OK) + return retval; + } + bp = bp->next; + } + + return ERROR_OK; +} + +/* TODO: HW data breakpoints are in EJTAG spec. Should we share it for MIPS32? */ +static int mips_mips64_set_watchpoint(struct target *target, + struct watchpoint *watchpoint) +{ + uint64_t wp_value; + struct mips64_common *mips64 = target->arch_info; + struct mips64_comparator *c, *cl = mips64->data_break_list; + int retval, wp_num = 0; + + /* + * watchpoint enabled, ignore all byte lanes in value register + * and exclude both load and store accesses from watchpoint + * condition evaluation + */ + int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE + | (0xff << EJTAG_DBCn_BLM_SHIFT); + + if (watchpoint->set) { + LOG_WARNING("watchpoint already set"); + return ERROR_OK; + } + + while (cl[wp_num].used && (wp_num < mips64->num_data_bpoints)) + wp_num++; + + if (wp_num >= mips64->num_data_bpoints) { + LOG_ERROR("ERROR Can not find free comparator"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + if (watchpoint->length != 4) { + LOG_ERROR("Only watchpoints of length 4 are supported"); + return ERROR_TARGET_UNALIGNED_ACCESS; + } + + if (watchpoint->address % 4) { + LOG_ERROR("Watchpoints address should be word aligned"); + return ERROR_TARGET_UNALIGNED_ACCESS; + } + + switch (watchpoint->rw) { + case WPT_READ: + enable &= ~EJTAG_DBCn_NOLB; + break; + case WPT_WRITE: + enable &= ~EJTAG_DBCn_NOSB; + break; + case WPT_ACCESS: + enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB); + break; + default: + LOG_ERROR("BUG: watchpoint->rw neither read, write nor access"); + } + + c = &cl[wp_num]; + watchpoint->set = wp_num + 1; + c->used = true; + c->bp_value = watchpoint->address; + + wp_value = watchpoint->address; + if (wp_value & 0x80000000) + wp_value |= ULLONG_MAX << 32; + + retval = target_write_u64(target, c->reg_address, wp_value); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u64(target, c->reg_address + 0x08, 0); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u64(target, c->reg_address + 0x10, 0); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u64(target, c->reg_address + 0x18, enable); + if (retval != ERROR_OK) + return retval; + + retval = target_write_u64(target, c->reg_address + 0x20, 0); + if (retval != ERROR_OK) + return retval; + + LOG_DEBUG("wp_num %i bp_value 0x%" PRIx64 "", wp_num, c->bp_value); + + return ERROR_OK; +} + +static int mips_mips64_enable_watchpoints(struct target *target) +{ + struct watchpoint *watchpoint = target->watchpoints; + int retval; + + /* set any pending watchpoints */ + while (watchpoint) { + if (watchpoint->set == 0) { + retval = mips_mips64_set_watchpoint(target, watchpoint); + if (retval != ERROR_OK) + return retval; + } + watchpoint = watchpoint->next; + } + + return ERROR_OK; +} + +static int mips_mips64_unset_hwbp(struct target *target, struct breakpoint *bp) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips64_comparator *comparator_list = mips64->inst_break_list; + int bp_num; + + bp_num = bp->set - 1; + + if ((bp_num < 0) || (bp_num >= mips64->num_inst_bpoints)) { + LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)", + bp->unique_id); + return ERROR_OK; + } + + LOG_DEBUG("bpid: %d - releasing hw: %d", bp->unique_id, bp_num); + comparator_list[bp_num].used = false; + comparator_list[bp_num].bp_value = 0; + + return target_write_u64(target, + comparator_list[bp_num].reg_address + 0x18, 0); +} + +static int mips_mips64_unset_sdbbp(struct target *target, struct breakpoint *bp) +{ + uint8_t buf[MIPS64_SDBBP_SIZE]; + uint32_t instr; + int retval; + + retval = target_read_memory(target, bp->address, MIPS64_SDBBP_SIZE, 1, + &buf[0]); + if (retval != ERROR_OK) + return retval; + + instr = target_buffer_get_u32(target, &buf[0]); + if (instr != MIPS64_SDBBP) + return ERROR_OK; + + return target_write_memory(target, bp->address, MIPS64_SDBBP_SIZE, 1, + bp->orig_instr); +} + +static int mips_mips16_unset_sdbbp(struct target *target, struct breakpoint *bp) +{ + uint8_t buf[MIPS16_SDBBP_SIZE]; + uint16_t instr; + int retval; + + retval = target_read_memory(target, bp->address, MIPS16_SDBBP_SIZE, 1, + &buf[0]); + if (retval != ERROR_OK) + return retval; + + instr = target_buffer_get_u16(target, &buf[0]); + if (instr != MIPS16_SDBBP(bp->length & 1)) + return ERROR_OK; + + return target_write_memory(target, bp->address, MIPS16_SDBBP_SIZE, 1, + bp->orig_instr); +} + +static int mips_mips64_unset_breakpoint(struct target *target, + struct breakpoint *bp) +{ + /* get pointers to arch-specific information */ + int retval; + + if (!bp->set) { + LOG_WARNING("breakpoint not set"); + return ERROR_OK; + } + + if (bp->type == BKPT_HARD) { + retval = mips_mips64_unset_hwbp(target, bp); + } else { + LOG_DEBUG("bpid: %d", bp->unique_id); + + switch (bp->length) { + case MIPS64_SDBBP_SIZE: + retval = mips_mips64_unset_sdbbp(target, bp); + break; + case MIPS16_SDBBP_SIZE: + retval = mips_mips16_unset_sdbbp(target, bp); + break; + default: + retval = ERROR_FAIL; + } + } + if (retval != ERROR_OK) { + LOG_ERROR("can't unset breakpoint. Some thing wrong happened"); + return retval; + } + + bp->set = false; + + return ERROR_OK; +} + +static int mips_mips64_resume(struct target *target, int current, + uint64_t address, int handle_breakpoints, + int debug_execution) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + int retval = ERROR_OK; + uint64_t resume_pc; + struct reg *pc; + + if (mips64->mips64mode32) + address = mips64_extend_sign(address); + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted %d", target->state); + return ERROR_TARGET_NOT_HALTED; + } + + if (!debug_execution) { + target_free_all_working_areas(target); + retval = mips_mips64_enable_breakpoints(target); + if (retval != ERROR_OK) + return retval; + + retval = mips_mips64_enable_watchpoints(target); + if (retval != ERROR_OK) + return retval; + } + + pc = &mips64->core_cache->reg_list[MIPS64_PC]; + /* current = 1: continue on current pc, otherwise continue at
*/ + if (!current) { + buf_set_u64(pc->value, 0, 64, address); + pc->dirty = 1; + pc->valid = 1; + } + + resume_pc = buf_get_u64(pc->value, 0, 64); + + retval = mips64_restore_context(target); + if (retval != ERROR_OK) + return retval; + + /* the front-end may request us not to handle breakpoints */ + if (handle_breakpoints) { + struct breakpoint *bp; + + /* Single step past breakpoint at current address */ + bp = breakpoint_find(target, (uint64_t) resume_pc); + if (bp) { + LOG_DEBUG("unset breakpoint at 0x%16.16" PRIx64 "", + bp->address); + retval = mips_mips64_unset_breakpoint(target, bp); + if (retval != ERROR_OK) + return retval; + + retval = mips_mips64_single_step_core(target); + if (retval != ERROR_OK) + return retval; + + retval = mips_mips64_set_breakpoint(target, bp); + if (retval != ERROR_OK) + return retval; + } + } + + /* enable interrupts if we are running */ + retval = mips64_enable_interrupts(target, !debug_execution); + if (retval != ERROR_OK) + return retval; + + /* exit debug mode */ + retval = mips64_ejtag_exit_debug(ejtag_info); + if (retval != ERROR_OK) + return retval; + + target->debug_reason = DBG_REASON_NOTHALTED; + + /* registers are now invalid */ + retval = mips64_invalidate_core_regs(target); + if (retval != ERROR_OK) + return retval; + + if (!debug_execution) { + target->state = TARGET_RUNNING; + retval = target_call_event_callbacks(target, + TARGET_EVENT_RESUMED); + if (retval != ERROR_OK) + return retval; + + LOG_DEBUG("target resumed at 0x%" PRIx64 "", resume_pc); + } else { + target->state = TARGET_DEBUG_RUNNING; + retval = target_call_event_callbacks(target, + TARGET_EVENT_DEBUG_RESUMED); + if (retval != ERROR_OK) + return retval; + + LOG_DEBUG("target debug resumed at 0x%" PRIx64 "", resume_pc); + } + + return ERROR_OK; +} + +static int mips_mips64_step(struct target *target, int current, + uint64_t address, int handle_breakpoints) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + struct reg *pc = &mips64->core_cache->reg_list[MIPS64_PC]; + struct breakpoint *bp = NULL; + int retval = ERROR_OK; + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (mips64->mips64mode32) + address = mips64_extend_sign(address); + + /* current = 1: continue on current pc, otherwise continue at + *
*/ + if (!current) { + buf_set_u64(pc->value, 0, 64, address); + pc->dirty = 1; + pc->valid = 1; + } + + /* the front-end may request us not to handle breakpoints */ + if (handle_breakpoints) { + bp = breakpoint_find(target, buf_get_u64(pc->value, 0, 64)); + if (bp) { + retval = mips_mips64_unset_breakpoint(target, bp); + if (retval != ERROR_OK) + return retval; + } + } + + retval = mips64_restore_context(target); + if (retval != ERROR_OK) + return retval; + + /* configure single step mode */ + retval = mips64_ejtag_config_step(ejtag_info, 1); + if (retval != ERROR_OK) + return retval; + + target->debug_reason = DBG_REASON_SINGLESTEP; + + retval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED); + if (retval != ERROR_OK) + return retval; + + /* disable interrupts while stepping */ + retval = mips64_enable_interrupts(target, false); + if (retval != ERROR_OK) + return retval; + + /* exit debug mode */ + retval = mips64_ejtag_exit_debug(ejtag_info); + if (retval != ERROR_OK) + return retval; + + /* registers are now invalid */ + retval = mips64_invalidate_core_regs(target); + if (retval != ERROR_OK) + return retval; + + if (bp) { + retval = mips_mips64_set_breakpoint(target, bp); + if (retval != ERROR_OK) + return retval; + } + + LOG_DEBUG("target stepped "); + + retval = mips_mips64_debug_entry(target); + if (retval != ERROR_OK) + return retval; + + return target_call_event_callbacks(target, TARGET_EVENT_HALTED); +} + +static int mips_mips64_add_breakpoint(struct target *target, + struct breakpoint *bp) +{ + struct mips64_common *mips64 = target->arch_info; + + if (mips64->mips64mode32) + bp->address = mips64_extend_sign(bp->address); + + if (bp->type == BKPT_HARD) { + if (mips64->num_inst_bpoints_avail < 1) { + LOG_INFO("no hardware breakpoint available"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + mips64->num_inst_bpoints_avail--; + } + + return mips_mips64_set_breakpoint(target, bp); +} + +static int mips_mips64_remove_breakpoint(struct target *target, + struct breakpoint *bp) +{ + /* get pointers to arch-specific information */ + struct mips64_common *mips64 = target->arch_info; + int retval = ERROR_OK; + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (bp->set) + retval = mips_mips64_unset_breakpoint(target, bp); + + if (bp->type == BKPT_HARD) + mips64->num_inst_bpoints_avail++; + + return retval; +} + +static int mips_mips64_unset_watchpoint(struct target *target, + struct watchpoint *watchpoint) +{ + /* get pointers to arch-specific information */ + struct mips64_common *mips64 = target->arch_info; + struct mips64_comparator *comparator_list = mips64->data_break_list; + + if (!watchpoint->set) { + LOG_WARNING("watchpoint not set"); + return ERROR_OK; + } + + int wp_num = watchpoint->set - 1; + if ((wp_num < 0) || (wp_num >= mips64->num_data_bpoints)) { + LOG_DEBUG("Invalid FP Comparator number in watchpoint"); + return ERROR_OK; + } + comparator_list[wp_num].used = false; + comparator_list[wp_num].bp_value = 0; + target_write_u64(target, comparator_list[wp_num].reg_address + 0x18, 0); + watchpoint->set = 0; + + return ERROR_OK; +} + +static int mips_mips64_add_watchpoint(struct target *target, + struct watchpoint *watchpoint) +{ + struct mips64_common *mips64 = target->arch_info; + + if (mips64->num_data_bpoints_avail < 1) { + LOG_INFO("no hardware watchpoints available"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + mips64->num_data_bpoints_avail--; + + return mips_mips64_set_watchpoint(target, watchpoint); +} + +static int mips_mips64_remove_watchpoint(struct target *target, + struct watchpoint *watchpoint) +{ + /* get pointers to arch-specific information */ + struct mips64_common *mips64 = target->arch_info; + int retval = ERROR_OK; + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (watchpoint->set) + retval = mips_mips64_unset_watchpoint(target, watchpoint); + + mips64->num_data_bpoints_avail++; + + return retval; +} + +static int mips_mips64_read_memory(struct target *target, uint64_t address, + uint32_t size, uint32_t count, uint8_t *buffer) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + int retval; + void *t; + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted %d", target->state); + return ERROR_TARGET_NOT_HALTED; + } + + if (mips64->mips64mode32) + address = mips64_extend_sign(address); + + /* sanitize arguments */ + if (((size != 8) && (size != 4) && (size != 2) && (size != 1)) + || !count || !buffer) + return ERROR_COMMAND_ARGUMENT_INVALID; + + if (((size == 8) && (address & 0x7)) || ((size == 4) && (address & 0x3)) + || ((size == 2) && (address & 0x1))) + return ERROR_TARGET_UNALIGNED_ACCESS; + + if (size > 1) { + t = calloc(count, size); + if (!t) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + } else + t = buffer; + + LOG_DEBUG("address: 0x%16.16" PRIx64 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", + address, size, count); + retval = mips64_pracc_read_mem(ejtag_info, address, size, count, + (void *)t); + + if (ERROR_OK != retval) { + LOG_ERROR("mips64_pracc_read_mem filed"); + goto read_done; + } + + switch (size) { + case 8: + target_buffer_set_u64_array(target, buffer, count, t); + break; + case 4: + target_buffer_set_u32_array(target, buffer, count, t); + break; + case 2: + target_buffer_set_u16_array(target, buffer, count, t); + break; + } + +read_done: + if (size > 1) + free(t); + + return retval; +} + +static int mips_mips64_bulk_write_memory(struct target *target, + target_addr_t address, uint32_t count, + const uint8_t *buffer) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + struct working_area *fast_data_area; + int retval; + + LOG_DEBUG("address: " TARGET_ADDR_FMT ", count: 0x%8.8" PRIx32 "", + address, count); + + if (address & 0x7) + return ERROR_TARGET_UNALIGNED_ACCESS; + + if (!mips64->fast_data_area) { + /* Get memory for block write handler + * we preserve this area between calls and gain a speed increase + * of about 3kb/sec when writing flash + * this will be released/nulled by the system when the target is resumed or reset */ + retval = target_alloc_working_area(target, + MIPS64_FASTDATA_HANDLER_SIZE, + &mips64->fast_data_area); + if (retval != ERROR_OK) { + LOG_ERROR("No working area available"); + return retval; + } + + /* reset fastadata state so the algo get reloaded */ + ejtag_info->fast_access_save = -1; + } + + fast_data_area = mips64->fast_data_area; + + if (address <= fast_data_area->address + fast_data_area->size && + fast_data_area->address <= address + count) { + LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area " + "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").", + fast_data_area->address, address, address + count); + LOG_ERROR("Change work-area-phys or load_image address!"); + return ERROR_FAIL; + } + + /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */ + /* but byte array represents target endianness */ + uint64_t *t; + + t = calloc(count, sizeof(uint64_t)); + if (!t) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + target_buffer_get_u64_array(target, buffer, count, t); + + retval = mips64_pracc_fastdata_xfer(ejtag_info, mips64->fast_data_area, + true, address, count, t); + + if (retval != ERROR_OK) + LOG_ERROR("Fastdata access Failed"); + + free(t); + + return retval; +} + +static int mips_mips64_write_memory(struct target *target, uint64_t address, + uint32_t size, uint32_t count, const uint8_t *buffer) +{ + struct mips64_common *mips64 = target->arch_info; + struct mips_ejtag *ejtag_info = &mips64->ejtag_info; + int retval; + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (mips64->mips64mode32) + address = mips64_extend_sign(address); + + /* sanitize arguments */ + if (((size != 8) && (size != 4) && (size != 2) && (size != 1)) + || !count || !buffer) + return ERROR_COMMAND_ARGUMENT_INVALID; + + if (((size == 8) && (address & 0x7)) || ((size == 4) && (address & 0x3)) + || ((size == 2) && (address & 0x1))) + return ERROR_TARGET_UNALIGNED_ACCESS; + + + + if (size == 8 && count > 8) { + retval = mips_mips64_bulk_write_memory(target, address, count, + buffer); + if (retval == ERROR_OK) + return ERROR_OK; + + LOG_WARNING("Falling back to non-bulk write"); + } + + void *t = NULL; + if (size > 1) { + t = calloc(count, size); + if (!t) { + LOG_ERROR("unable to allocate t for write buffer"); + return ERROR_FAIL; + } + + switch (size) { + case 8: + target_buffer_get_u64_array(target, buffer, count, + (uint64_t *)t); + break; + case 4: + target_buffer_get_u32_array(target, buffer, count, + (uint32_t *)t); + break; + case 2: + target_buffer_get_u16_array(target, buffer, count, + (uint16_t *)t); + break; + } + buffer = t; + } + + LOG_DEBUG("address: 0x%16.16" PRIx64 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", + address, size, count); + + retval = mips64_pracc_write_mem(ejtag_info, address, size, count, + (void *)buffer); + free(t); + + return retval; +} + +static int mips_mips64_init_target(struct command_context *cmd_ctx, + struct target *target) +{ + return mips64_build_reg_cache(target); +} + +static int mips_mips64_target_create(struct target *target, Jim_Interp *interp) +{ + struct mips_mips64_common *mips_mips64; + struct mips64_common *mips64; + + mips_mips64 = calloc(1, sizeof(*mips_mips64)); + if (!mips_mips64) { + LOG_ERROR("unable to allocate mips_mips64"); + return ERROR_FAIL; + } + + mips_mips64->common_magic = MIPS64_COMMON_MAGIC; + + mips64 = &mips_mips64->mips64_common; + mips64->arch_info = mips_mips64; + target->arch_info = mips64; + + return mips64_init_arch_info(target, mips64, target->tap); +} + +static int mips_mips64_examine(struct target *target) +{ + int retval; + struct mips64_common *mips64 = target->arch_info; + + retval = mips_ejtag_init(&mips64->ejtag_info); + if (retval != ERROR_OK) + return retval; + + return mips64_examine(target); +} + +static int mips_mips64_checksum_memory(struct target *target, uint64_t address, + uint32_t size, uint32_t *checksum) +{ + return ERROR_FAIL; /* use bulk read method */ +} + +COMMAND_HANDLER(handle_mips64mode32) +{ + struct target *target = get_current_target(CMD_CTX); + struct mips64_common *mips64 = target->arch_info; + + if (CMD_ARGC > 0) + COMMAND_PARSE_BOOL(CMD_ARGV[0], mips64->mips64mode32, "on", "off"); + + if (mips64->mips64mode32) + command_print(CMD, "enabled"); + else + command_print(CMD, "disabled"); + + return ERROR_OK; +} + + +static const struct command_registration mips64_commands_handlers[] = { + { + .name = "mips64mode32", + .mode = COMMAND_EXEC, + .help = "Enable/disable 32 bit mode", + .usage = "[1|0]", + .handler = handle_mips64mode32 + }, + COMMAND_REGISTRATION_DONE +}; + +struct target_type mips_mips64_target = { + .name = "mips_mips64", + + .poll = mips_mips64_poll, + .arch_state = mips64_arch_state, + + .target_request_data = NULL, + + .halt = mips_mips64_halt, + .resume = mips_mips64_resume, + .step = mips_mips64_step, + + .assert_reset = mips_mips64_assert_reset, + .deassert_reset = mips_mips64_deassert_reset, + .soft_reset_halt = mips_mips64_soft_reset_halt, + + .get_gdb_reg_list = mips64_get_gdb_reg_list, + + .read_memory = mips_mips64_read_memory, + .write_memory = mips_mips64_write_memory, + .checksum_memory = mips_mips64_checksum_memory, + .blank_check_memory = NULL, + + .run_algorithm = mips64_run_algorithm, + + .add_breakpoint = mips_mips64_add_breakpoint, + .remove_breakpoint = mips_mips64_remove_breakpoint, + .add_watchpoint = mips_mips64_add_watchpoint, + .remove_watchpoint = mips_mips64_remove_watchpoint, + + .target_create = mips_mips64_target_create, + .init_target = mips_mips64_init_target, + .examine = mips_mips64_examine, + + .commands = mips64_commands_handlers, +}; + +#endif /* BUILD_TARGET64 */ diff --git a/src/target/mips_mips64.h b/src/target/mips_mips64.h new file mode 100644 index 000000000..69fb2a6f9 --- /dev/null +++ b/src/target/mips_mips64.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * MIPS64 generic target support * + * + * Copyright (C) 2014 by Andrey Sidorov + * Copyright (C) 2014 by Aleksey Kuleshov + * Copyright (C) 2014-2019 by Peter Mamonov + * + * Based on the work of: + * Copyright (C) 2008 by Spencer Oliver + * Copyright (C) 2008 by David T.L. Wong + */ + +#ifndef OPENOCD_TARGET_MIPS_MIPS64_H +#define OPENOCD_TARGET_MIPS_MIPS64_H + +#include "helper/types.h" + +struct mips_mips64_common { + int common_magic; + struct mips64_common mips64_common; +}; + +#endif /* OPENOCD_TARGET_MIPS_MIPS64_H */ diff --git a/src/target/target.c b/src/target/target.c index 03b6f4eb2..2bfbd5700 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -94,6 +94,7 @@ extern struct target_type cortexr4_target; extern struct target_type arm11_target; extern struct target_type ls1_sap_target; extern struct target_type mips_m4k_target; +extern struct target_type mips_mips64_target; extern struct target_type avr_target; extern struct target_type dsp563xx_target; extern struct target_type dsp5680xx_target; @@ -147,6 +148,7 @@ static struct target_type *target_types[] = { &esirisc_target, #if BUILD_TARGET64 &aarch64_target, + &mips_mips64_target, #endif NULL, }; From 678fb4f60b685ed79d35272bc515891fa53b527e Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Wed, 27 Nov 2019 19:10:34 +0100 Subject: [PATCH 039/354] target/stm32h7x: add support of dual core variant of STM32H7 STM32H7x7 and STM32H7x5 devices contains two cores : CM7 + CM4 The second core creation is only done when * DUAL_CORE variable is set to true * non HLA interface is used A second check for the second core existence is done in cpu1 examine-end Once the second core is detected it gets examined. Furthermore, the script provides a configurable CTI usage in order to halt the cores simultaneously. Tested on Rev X and V devices. PS: the indentation was a mix of spaces and tabs, all changed to tabs. Change-Id: Iad9c30826965ddb9be5dee628bc2e63f953bbcb8 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5130 Tested-by: jenkins Reviewed-by: Tomas Vanek --- contrib/loaders/flash/stm32/stm32h7x.S | 2 +- src/flash/nor/stm32h7x.c | 2 +- tcl/board/st_nucleo_h745zi.cfg | 16 +++ tcl/target/stm32h7x.cfg | 152 ++++++++++++++++++++++--- tcl/target/stm32h7x_dual_bank.cfg | 7 +- 5 files changed, 160 insertions(+), 19 deletions(-) create mode 100644 tcl/board/st_nucleo_h745zi.cfg diff --git a/contrib/loaders/flash/stm32/stm32h7x.S b/contrib/loaders/flash/stm32/stm32h7x.S index f0d32956f..beb8fdbd4 100644 --- a/contrib/loaders/flash/stm32/stm32h7x.S +++ b/contrib/loaders/flash/stm32/stm32h7x.S @@ -18,7 +18,7 @@ .text .syntax unified - .cpu cortex-m7 + .cpu cortex-m4 .thumb /* diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index aec836b19..736c8d2c4 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -136,7 +136,7 @@ enum stm32h7x_opt_rdp { }; static const struct stm32h7x_rev stm32_450_revs[] = { - { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X" }, + { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X" }, { 0x2003, "V" }, }; static const struct stm32h7x_part_info stm32h7x_parts[] = { diff --git a/tcl/board/st_nucleo_h745zi.cfg b/tcl/board/st_nucleo_h745zi.cfg new file mode 100644 index 000000000..bb8a396b5 --- /dev/null +++ b/tcl/board/st_nucleo_h745zi.cfg @@ -0,0 +1,16 @@ +# This is an ST NUCLEO-H745ZI-Q board with single STM32H745ZITx chip. + +source [find interface/stlink.cfg] +transport select hla_swd + +# ST-Link HLA interface do not support multi-AP debugging +# then setting DUAL_CORE and USE_CTI has no effect, because +# it will fall back to single core configuration +set DUAL_CORE 1 +set USE_CTI 1 + +source [find target/stm32h7x_dual_bank.cfg] + +# when using ST-Link HLA adapter, DBGMCU accesses are done via AP0 +# unfortunately DBGMCU is not accessible when SRST is asserted +reset_config srst_only diff --git a/tcl/target/stm32h7x.cfg b/tcl/target/stm32h7x.cfg index ef9e29ac7..1d116542a 100644 --- a/tcl/target/stm32h7x.cfg +++ b/tcl/target/stm32h7x.cfg @@ -12,6 +12,39 @@ if { [info exists CHIPNAME] } { set _CHIPNAME stm32h7x } +if { [info exists DUAL_BANK] } { + set $_CHIPNAME.DUAL_BANK $DUAL_BANK + unset DUAL_BANK +} else { + set $_CHIPNAME.DUAL_BANK 0 +} + +if { [info exists DUAL_CORE] } { + set $_CHIPNAME.DUAL_CORE $DUAL_CORE + unset DUAL_CORE +} else { + set $_CHIPNAME.DUAL_CORE 0 +} + +# Issue a warning when hla is used, and fallback to single core configuration +if { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } { + echo "Warning : hla does not support multicore debugging" + set $_CHIPNAME.DUAL_CORE 0 +} + +if { [info exists USE_CTI] } { + set $_CHIPNAME.USE_CTI $USE_CTI + unset USE_CTI +} else { + set $_CHIPNAME.USE_CTI 0 +} + +# Issue a warning when DUAL_CORE=0 and USE_CTI=1, and fallback to USE_CTI=0 +if { ![set $_CHIPNAME.DUAL_CORE] && [set $_CHIPNAME.USE_CTI] } { + echo "Warning : could not use CTI with a single core device, CTI is disabled" + set $_CHIPNAME.USE_CTI 0 +} + set _ENDIAN little # Work-area is a space in RAM used for flash programming @@ -46,13 +79,30 @@ if {![using_hla]} { target create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2 } -set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 0 +target create $_CHIPNAME.cpu0 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 0 -$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 +$_CHIPNAME.cpu0 configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME stm32h7x 0x08000000 0 0 0 $_TARGETNAME +flash bank $_CHIPNAME.bank1.cpu0 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu0 + +if {[set $_CHIPNAME.DUAL_BANK]} { + flash bank $_CHIPNAME.bank2.cpu0 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu0 +} + +if {[set $_CHIPNAME.DUAL_CORE]} { + target create $_CHIPNAME.cpu1 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 3 + + $_CHIPNAME.cpu1 configure -work-area-phys 0x38000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + + flash bank $_CHIPNAME.bank1.cpu1 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu1 + + if {[set $_CHIPNAME.DUAL_BANK]} { + flash bank $_CHIPNAME.bank2.cpu1 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu1 + } +} + +# Make sure that cpu0 is selected +targets $_CHIPNAME.cpu0 # Clock after reset is HSI at 64 MHz, no need of PLL adapter_khz 1800 @@ -78,7 +128,11 @@ reset_config srst_only srst_nogate if {![using_hla]} { # if srst is not fitted use SYSRESETREQ to # perform a soft reset - cortex_m reset_config sysresetreq + $_CHIPNAME.cpu0 cortex_m reset_config sysresetreq + + if {[set $_CHIPNAME.DUAL_CORE]} { + $_CHIPNAME.cpu1 cortex_m reset_config sysresetreq + } # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3 @@ -89,34 +143,56 @@ if {![using_hla]} { $_CHIPNAME.dap apcsw 0x08000000 0x08000000 } -$_TARGETNAME configure -event examine-end { +$_CHIPNAME.cpu0 configure -event examine-end { # Enable D3 and D1 DBG clocks # DBGMCU_CR |= D3DBGCKEN | D1DBGCKEN stm32h7x_dbgmcu_mmw 0x004 0x00600000 0 # Enable debug during low power modes (uses more power) - # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP in D3 & D1 Domains - stm32h7x_dbgmcu_mmw 0x004 0x00000187 0 + # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP in D3, D2 & D1 Domains + stm32h7x_dbgmcu_mmw 0x004 0x000001BF 0 # Stop watchdog counters during halt # DBGMCU_APB3FZ1 |= WWDG1 stm32h7x_dbgmcu_mmw 0x034 0x00000040 0 - # DBGMCU_APB4FZ1 |= WDGLSD1 - stm32h7x_dbgmcu_mmw 0x054 0x00040000 0 + # DBGMCU_APB1LFZ1 |= WWDG2 + stm32h7x_dbgmcu_mmw 0x03C 0x00000800 0 + # DBGMCU_APB4FZ1 |= WDGLSD1 | WDGLSD2 + stm32h7x_dbgmcu_mmw 0x054 0x000C0000 0 } -$_TARGETNAME configure -event trace-config { +$_CHIPNAME.cpu0 configure -event trace-config { # Set TRACECLKEN; TRACE_MODE is set to async; when using sync # change this value accordingly to configure trace pins # assignment stm32h7x_dbgmcu_mmw 0x004 0x00100000 0 } -$_TARGETNAME configure -event reset-init { +$_CHIPNAME.cpu0 configure -event reset-init { # Clock after reset is HSI at 64 MHz, no need of PLL adapter_khz 4000 } +if {[set $_CHIPNAME.DUAL_CORE]} { + $_CHIPNAME.cpu1 configure -event examine-end { + # get _CHIPNAME from the current target + set _CHIPNAME [regsub ".cpu\\d$" [target current] ""] + global $_CHIPNAME.USE_CTI + + # Stop watchdog counters during halt + # DBGMCU_APB3FZ2 |= WWDG1 + stm32h7x_dbgmcu_mmw 0x038 0x00000040 0 + # DBGMCU_APB1LFZ2 |= WWDG2 + stm32h7x_dbgmcu_mmw 0x040 0x00000800 0 + # DBGMCU_APB4FZ2 |= WDGLSD1 | WDGLSD2 + stm32h7x_dbgmcu_mmw 0x058 0x000C0000 0 + + if {[set $_CHIPNAME.USE_CTI]} { + stm32h7x_cti_start + } + } +} + # like mrw, but with target selection proc stm32h7x_mrw {used_target reg} { set value "" @@ -147,3 +223,53 @@ proc stm32h7x_dbgmcu_mmw {reg_offset setbits clearbits} { stm32h7x_mmw $used_target $reg_addr $setbits $clearbits } + +if {[set $_CHIPNAME.USE_CTI]} { + # create CTI instances for both cores + cti create $_CHIPNAME.cti0 -dap $_CHIPNAME.dap -ap-num 0 -ctibase 0xE0043000 + cti create $_CHIPNAME.cti1 -dap $_CHIPNAME.dap -ap-num 3 -ctibase 0xE0043000 + + $_CHIPNAME.cpu0 configure -event halted { stm32h7x_cti_prepare_restart_all } + $_CHIPNAME.cpu1 configure -event halted { stm32h7x_cti_prepare_restart_all } + + $_CHIPNAME.cpu0 configure -event debug-halted { stm32h7x_cti_prepare_restart_all } + $_CHIPNAME.cpu1 configure -event debug-halted { stm32h7x_cti_prepare_restart_all } + + proc stm32h7x_cti_start {} { + # get _CHIPNAME from the current target + set _CHIPNAME [regsub ".cpu\\d$" [target current] ""] + + # Configure Cores' CTIs to halt each other + # TRIGIN0 (DBGTRIGGER) and TRIGOUT0 (EDBGRQ) at CTM_CHANNEL_0 + $_CHIPNAME.cti0 write INEN0 0x1 + $_CHIPNAME.cti0 write OUTEN0 0x1 + $_CHIPNAME.cti1 write INEN0 0x1 + $_CHIPNAME.cti1 write OUTEN0 0x1 + + # enable CTIs + $_CHIPNAME.cti0 enable on + $_CHIPNAME.cti1 enable on + } + + proc stm32h7x_cti_stop {} { + # get _CHIPNAME from the current target + set _CHIPNAME [regsub ".cpu\\d$" [target current] ""] + + $_CHIPNAME.cti0 enable off + $_CHIPNAME.cti1 enable off + } + + proc stm32h7x_cti_prepare_restart_all {} { + stm32h7x_cti_prepare_restart cti0 + stm32h7x_cti_prepare_restart cti1 + } + + proc stm32h7x_cti_prepare_restart {cti} { + # get _CHIPNAME from the current target + set _CHIPNAME [regsub ".cpu\\d$" [target current] ""] + + # Acknowlodge EDBGRQ at TRIGOUT0 + $_CHIPNAME.$cti write INACK 0x01 + $_CHIPNAME.$cti write INACK 0x00 + } +} diff --git a/tcl/target/stm32h7x_dual_bank.cfg b/tcl/target/stm32h7x_dual_bank.cfg index 7e342f931..a88d70dcf 100644 --- a/tcl/target/stm32h7x_dual_bank.cfg +++ b/tcl/target/stm32h7x_dual_bank.cfg @@ -1,7 +1,6 @@ # script for stm32h7x family (dual flash bank) -source [find target/stm32h7x.cfg] # STM32H7xxxI 2Mo have a dual bank flash. -# Add the second flash bank. -set _FLASHNAME $_CHIPNAME.flash1 -flash bank $_FLASHNAME stm32h7x 0x08100000 0 0 0 $_TARGETNAME +set DUAL_BANK 1 + +source [find target/stm32h7x.cfg] From 1e427fd580ad94bb3bf29d4e02ef81361c920f28 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Wed, 6 Nov 2019 19:04:57 +0300 Subject: [PATCH 040/354] server: gdb_server: fix memory map generation on a 32-bit BE host Due to lack of printf format check wrong specifier was used and it actually broke operation on a 32-bit BE host. So fix this and add the necessary function attributes so that the bugs like that can be uncovered automaticaly. Reported and pinpointed by Karl Palsson on IRC. Change-Id: I254ec28fcd9bb30594d607f74a6dba5456c2c7a1 Tested-by: Karl Palsson Signed-off-by: Paul Fertser Reviewed-on: http://openocd.zylin.com/5342 Tested-by: jenkins Reviewed-by: Karl Palsson Reviewed-by: Antonio Borneo --- src/helper/log.h | 3 ++- src/server/gdb_server.c | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/helper/log.h b/src/helper/log.h index d60587f72..bc08fe49a 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -95,7 +95,8 @@ int log_add_callback(log_callback_fn fn, void *priv); int log_remove_callback(log_callback_fn fn, void *priv); char *alloc_vprintf(const char *fmt, va_list ap); -char *alloc_printf(const char *fmt, ...); +char *alloc_printf(const char *fmt, ...) + __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 2))); extern int debug_level; diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index c8f0e523c..49939a5cb 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1729,8 +1729,8 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection, /* print out a string and allocate more space as needed, * mainly used for XML at this point */ -static void xml_printf(int *retval, char **xml, int *pos, int *size, - const char *fmt, ...) +static __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6))) void xml_printf(int *retval, + char **xml, int *pos, int *size, const char *fmt, ...) { if (*retval != ERROR_OK) return; @@ -1871,7 +1871,7 @@ static int gdb_memory_map(struct connection *connection, if (ram_start < p->base) xml_printf(&retval, &xml, &pos, &size, "\n", + "length=\"" TARGET_ADDR_FMT "\"/>\n", ram_start, p->base - ram_start); /* Report adjacent groups of same-size sectors. So for @@ -2469,7 +2469,7 @@ static int gdb_generate_thread_list(struct target *target, char **thread_list_ou xml_printf(&retval, &thread_list, &pos, &size, ", "); xml_printf(&retval, &thread_list, &pos, &size, - thread_detail->extra_info_str); + "%s", thread_detail->extra_info_str); } xml_printf(&retval, &thread_list, &pos, &size, @@ -3555,7 +3555,7 @@ static int gdb_target_add_one(struct target *target) if (parse_long(gdb_port_next, &portnumber) == ERROR_OK) { free(gdb_port_next); if (portnumber) { - gdb_port_next = alloc_printf("%d", portnumber+1); + gdb_port_next = alloc_printf("%ld", portnumber+1); } else { /* Don't increment if gdb_port is 0, since we're just * trying to allocate an unused port. */ From 0f12d792ed5ab2b8f934e689b8a23f8c55f1f218 Mon Sep 17 00:00:00 2001 From: Jimmy Date: Thu, 5 Dec 2019 14:45:17 +0800 Subject: [PATCH 041/354] server/tcl_server.c: Fix buffer overrun The input buffer size is checked only after writing past its end. Change-Id: I6a9651c5b7d82efe338468d67bf6caca41004b01 Signed-off-by: Jimmy Reviewed-on: http://openocd.zylin.com/5352 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/server/tcl_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c index 1ec45ffbb..1735c43ff 100644 --- a/src/server/tcl_server.c +++ b/src/server/tcl_server.c @@ -199,7 +199,7 @@ static int tcl_input(struct connection *connection) for (i = 0; i < rlen; i++) { /* buffer the data */ tclc->tc_line[tclc->tc_lineoffset] = in[i]; - if (tclc->tc_lineoffset < tclc->tc_line_size) { + if (tclc->tc_lineoffset + 1 < tclc->tc_line_size) { tclc->tc_lineoffset++; } else if (tclc->tc_line_size >= TCL_LINE_MAX) { /* maximum line size reached, drop line */ From 22b4abc46c552bfc21003853b74e732da773cd1d Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Thu, 9 May 2019 16:38:47 +0200 Subject: [PATCH 042/354] flash/nor/nrf5: remove check for protected sector The new "Access control list" flash protection scheme used in nRF52840 is not yet supported. Do not prevent sector erase if protection state is unknown. Change-Id: Iae9a869a54ffbdc888fb3ec478dafb5c942d9ea0 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5348 Tested-by: jenkins --- src/flash/nor/nrf5.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index c1fd257ef..d923468fd 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -859,10 +859,6 @@ static int nrf5_erase_page(struct flash_bank *bank, int res; LOG_DEBUG("Erasing page at 0x%"PRIx32, sector->offset); - if (sector->is_protected) { - LOG_ERROR("Cannot erase protected sector at 0x%" PRIx32, sector->offset); - return ERROR_FAIL; - } if (bank->base == NRF5_UICR_BASE) { if (chip->features & NRF5_FEATURE_SERIES_51) { From 881484708d0399007df1fa1b1a844f0dc95bf0ce Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Thu, 2 May 2019 11:53:15 +0200 Subject: [PATCH 043/354] jtag_vpi: ensured constant packet size & endianness Made sure that size and endianness of jtag_vpi structures sent over the network is the same, regardless of the platform. Little endian chosen to maintain as much compatibility with existing OpenOCD builds as possible. Matching change in the original jtag_vpi server: https://github.com/fjullien/jtag_vpi/pull/4 Change-Id: Ib839fea9bb2d5190b5643c970b89333b286dce71 Signed-off-by: Jan Matyas Reviewed-on: http://openocd.zylin.com/5152 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/jtag/drivers/jtag_vpi.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c index 3e39420fb..27b9da116 100644 --- a/src/jtag/drivers/jtag_vpi.c +++ b/src/jtag/drivers/jtag_vpi.c @@ -53,16 +53,34 @@ char *server_address; int sockfd; struct sockaddr_in serv_addr; +/* One jtag_vpi "packet" as sent over a TCP channel. */ struct vpi_cmd { - int cmd; + union { + uint32_t cmd; + unsigned char cmd_buf[4]; + }; unsigned char buffer_out[XFERT_MAX_SIZE]; unsigned char buffer_in[XFERT_MAX_SIZE]; - int length; - int nb_bits; + union { + uint32_t length; + unsigned char length_buf[4]; + }; + union { + uint32_t nb_bits; + unsigned char nb_bits_buf[4]; + }; }; static int jtag_vpi_send_cmd(struct vpi_cmd *vpi) { + /* Use little endian when transmitting/receiving jtag_vpi cmds. + The choice of little endian goes against usual networking conventions + but is intentional to remain compatible with most older OpenOCD builds + (i.e. builds on little-endian platforms). */ + h_u32_to_le(vpi->cmd_buf, vpi->cmd); + h_u32_to_le(vpi->length_buf, vpi->length); + h_u32_to_le(vpi->nb_bits_buf, vpi->nb_bits); + int retval = write_socket(sockfd, vpi, sizeof(struct vpi_cmd)); if (retval <= 0) return ERROR_FAIL; @@ -76,6 +94,11 @@ static int jtag_vpi_receive_cmd(struct vpi_cmd *vpi) if (retval < (int)sizeof(struct vpi_cmd)) return ERROR_FAIL; + /* Use little endian when transmitting/receiving jtag_vpi cmds. */ + vpi->cmd = le_to_h_u32(vpi->cmd_buf); + vpi->length = le_to_h_u32(vpi->length_buf); + vpi->nb_bits = le_to_h_u32(vpi->nb_bits_buf); + return ERROR_OK; } From 104a5cbef8965d47b9111f7e010f96ebb5fdf06c Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 10 Dec 2019 19:49:01 +0100 Subject: [PATCH 044/354] flash/nor/stm32f2x: fix clang static analyzer warning Using a signed variable as a parameter of FLASH_SNB() macro generated "warning: The result of the left shift is undefined because the left operand is negative" Change-Id: I8b3fe840f9308962460906097df6ddd848c07b25 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5356 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/stm32f2x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c index b49e76e32..ea35fd05d 100644 --- a/src/flash/nor/stm32f2x.c +++ b/src/flash/nor/stm32f2x.c @@ -634,7 +634,7 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last) */ for (i = first; i <= last; i++) { - int snb; + unsigned int snb; if (stm32x_info->has_large_mem && i >= 12) snb = (i - 12) | 0x10; else From f476c9eec42d551bc9015089abc47b09058f06b5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 17 Oct 2019 18:02:38 +0200 Subject: [PATCH 045/354] gdb_server: fix string length with semihosting_fileio The GDB file-I/O remote protocol extension, used for implementing the semihosting file I/O, requires the length of strings to include the trailing zero character, as explicitly stated inside a comment in GDB source code [1]: /* 1. Parameter: Ptr to pathname / length incl. trailing zero. */ ARM specification for semihosting [2] requires the string length to not include the trailing zero character, e.g. in SYS_OPEN specifications: "field 3: An integer that gives the length of the string pointed to by field 1. The length does not include the terminating null character that must be present." The mismatch above requires OpenOCD to add "one" to the string length before passing it to GDB. Such conversion is missing either in the generic semihosting provider of the data, the function semihosting_common(), and in the consumer of the data, the gdb_server function gdb_fileio_reply(). The conversion is already implemented in the target specific function nds32_get_gdb_fileio_info(), but it's not the preferred place for such GDB specific requirement. This issue affects the semihosting calls "open", "unlink", "rename" and "system". Remove the "+1" conversion from nds32_get_gdb_fileio_info(). Add the "+1" conversion in gdb_fileio_reply(). [1] http://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;f=gdb/remote-fileio.c;h=11c141e42c4d#l381 [2] "Semihosting for AArch32 and AArch64, Release 2.0" https://static.docs.arm.com/100863/0200/semihosting.pdf Change-Id: I35461bcb30f734fe2d51f7f0d418e3d04b4af506 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5322 Tested-by: jenkins Reviewed-by: Steven Stallion Reviewed-by: Muhammad Omair Javaid Reviewed-by: Tomas Vanek --- src/server/gdb_server.c | 10 +++++----- src/target/nds32.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 49939a5cb..12c03a515 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -800,7 +800,7 @@ static void gdb_fileio_reply(struct target *target, struct connection *connectio if (strcmp(target->fileio_info->identifier, "open") == 0) sprintf(fileio_command, "F%s,%" PRIx64 "/%" PRIx64 ",%" PRIx64 ",%" PRIx64, target->fileio_info->identifier, target->fileio_info->param_1, - target->fileio_info->param_2, + target->fileio_info->param_2 + 1, /* len + trailing zero */ target->fileio_info->param_3, target->fileio_info->param_4); else if (strcmp(target->fileio_info->identifier, "close") == 0) @@ -824,13 +824,13 @@ static void gdb_fileio_reply(struct target *target, struct connection *connectio else if (strcmp(target->fileio_info->identifier, "rename") == 0) sprintf(fileio_command, "F%s,%" PRIx64 "/%" PRIx64 ",%" PRIx64 "/%" PRIx64, target->fileio_info->identifier, target->fileio_info->param_1, - target->fileio_info->param_2, + target->fileio_info->param_2 + 1, /* len + trailing zero */ target->fileio_info->param_3, - target->fileio_info->param_4); + target->fileio_info->param_4 + 1); /* len + trailing zero */ else if (strcmp(target->fileio_info->identifier, "unlink") == 0) sprintf(fileio_command, "F%s,%" PRIx64 "/%" PRIx64, target->fileio_info->identifier, target->fileio_info->param_1, - target->fileio_info->param_2); + target->fileio_info->param_2 + 1); /* len + trailing zero */ else if (strcmp(target->fileio_info->identifier, "stat") == 0) sprintf(fileio_command, "F%s,%" PRIx64 "/%" PRIx64 ",%" PRIx64, target->fileio_info->identifier, target->fileio_info->param_1, @@ -850,7 +850,7 @@ static void gdb_fileio_reply(struct target *target, struct connection *connectio else if (strcmp(target->fileio_info->identifier, "system") == 0) sprintf(fileio_command, "F%s,%" PRIx64 "/%" PRIx64, target->fileio_info->identifier, target->fileio_info->param_1, - target->fileio_info->param_2); + target->fileio_info->param_2 + 1); /* len + trailing zero */ else if (strcmp(target->fileio_info->identifier, "exit") == 0) { /* If target hits exit syscall, report to GDB the program is terminated. * In addition, let target run its own exit syscall handler. */ diff --git a/src/target/nds32.c b/src/target/nds32.c index 4115ea4f2..f40ce534b 100644 --- a/src/target/nds32.c +++ b/src/target/nds32.c @@ -2361,7 +2361,7 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil fileio_info->param_4 = reg_r2; target->type->read_buffer(target, reg_r0, 256, filename); - fileio_info->param_2 = strlen((char *)filename) + 1; + fileio_info->param_2 = strlen((char *)filename); } break; case NDS32_SYSCALL_CLOSE: @@ -2399,7 +2399,7 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil /* reserve fileio_info->param_2 for length of path */ target->type->read_buffer(target, reg_r0, 256, filename); - fileio_info->param_2 = strlen((char *)filename) + 1; + fileio_info->param_2 = strlen((char *)filename); } break; case NDS32_SYSCALL_RENAME: @@ -2413,10 +2413,10 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil /* reserve fileio_info->param_4 for length of new path */ target->type->read_buffer(target, reg_r0, 256, filename); - fileio_info->param_2 = strlen((char *)filename) + 1; + fileio_info->param_2 = strlen((char *)filename); target->type->read_buffer(target, reg_r1, 256, filename); - fileio_info->param_4 = strlen((char *)filename) + 1; + fileio_info->param_4 = strlen((char *)filename); } break; case NDS32_SYSCALL_FSTAT: @@ -2458,7 +2458,7 @@ int nds32_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fil /* reserve fileio_info->param_2 for length of old path */ target->type->read_buffer(target, reg_r0, 256, command); - fileio_info->param_2 = strlen((char *)command) + 1; + fileio_info->param_2 = strlen((char *)command); } break; case NDS32_SYSCALL_ERRNO: From 964c4db9cec3e619545490ccb525be210e8008d5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 27 Sep 2019 12:27:01 +0200 Subject: [PATCH 046/354] gdb_server: fix extended_protocol for multi-target The flag extended_protocol is currently a single static variable thus, in case of multiple targets, it is shared among all the gdb connections. This is an issue if the gdb connections are not all using extended protocol, but also when one connection get closed because the code sets the flag to zero impacting the other connections still open. Move the flag extended_protocol in the per-connection struct gdb_connection. Change-Id: I19d565f925df6a31767fd8d392242f60867109f2 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5310 Tested-by: jenkins Reviewed-by: Moritz Fischer Reviewed-by: Tomas Vanek --- src/server/gdb_server.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 12c03a515..9f1cb7b07 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -91,6 +91,8 @@ struct gdb_connection { * normally we reply with a S reply via gdb_last_signal_packet. * as a side note this behaviour only effects gdb > 6.8 */ bool attached; + /* set when extended protocol is used */ + bool extended_protocol; /* temporarily used for target description support */ struct target_desc_format target_desc; /* temporarily used for thread list support */ @@ -949,6 +951,7 @@ static int gdb_new_connection(struct connection *connection) gdb_connection->sync = false; gdb_connection->mem_write_error = false; gdb_connection->attached = true; + gdb_connection->extended_protocol = false; gdb_connection->target_desc.tdesc = NULL; gdb_connection->target_desc.tdesc_length = 0; gdb_connection->thread_list = NULL; @@ -3228,7 +3231,6 @@ static int gdb_input_inner(struct connection *connection) int packet_size; int retval; struct gdb_connection *gdb_con = connection->priv; - static int extended_protocol; target = get_target_from_connection(connection); @@ -3380,7 +3382,6 @@ static int gdb_input_inner(struct connection *connection) break; case 'D': retval = gdb_detach(connection); - extended_protocol = 0; break; case 'X': retval = gdb_write_memory_binary_packet(connection, packet, packet_size); @@ -3388,7 +3389,7 @@ static int gdb_input_inner(struct connection *connection) return retval; break; case 'k': - if (extended_protocol != 0) { + if (gdb_con->extended_protocol) { gdb_con->attached = false; break; } @@ -3396,7 +3397,7 @@ static int gdb_input_inner(struct connection *connection) return ERROR_SERVER_REMOTE_CLOSED; case '!': /* handle extended remote protocol */ - extended_protocol = 1; + gdb_con->extended_protocol = true; gdb_put_packet(connection, "OK", 2); break; case 'R': From 49d71d06d19e1b5006c8be5b35319658654dfe21 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 5 Sep 2019 10:48:12 +0200 Subject: [PATCH 047/354] sysfsgpio: give time to udev to change gpio permission When a gpio is exported by writing in /sys/class/gpio/export, the corresponding gpio control files appear immediately in sysfs but with default access permission for root user only. The daemon udev requires some time to get notified of the new files before it can change the permissions to allow access to unprivileged users. Due to this race condition, sysfsgpio can fail with EACCES error if OpenOCD is executed by any unprivileged user. Give 0.5 seconds to udev to identify the new files and change the permission. Tested with udev rules: SUBSYSTEM=="gpio*", PROGRAM="/bin/sh -c 'find -L /sys/class/gpio/ -maxdepth 2 -exec chown root:uucp {} \; -exec chmod g=u {} \; || true'" Change-Id: I1316c66ff103ffe23e5e4720f33372dc272a3766 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5302 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/drivers/sysfsgpio.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index eb4941e6b..c6ffa3205 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -52,6 +52,7 @@ #include "config.h" #endif +#include #include #include "bitbang.h" @@ -112,6 +113,7 @@ static void unexport_sysfs_gpio(int gpio) */ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) { + struct timeval timeout, now; char buf[40]; char gpiostr[5]; int ret; @@ -131,8 +133,19 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) } } + gettimeofday(&timeout, NULL); + timeval_add_time(&timeout, 0, 500000); + snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); - ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); + for (;;) { + ret = open_write_close(buf, is_output ? (init_high ? "high" : "low") : "in"); + if (ret >= 0 || errno != EACCES) + break; + gettimeofday(&now, NULL); + if (timeval_compare(&now, &timeout) >= 0) + break; + jtag_sleep(10000); + } if (ret < 0) { LOG_ERROR("Couldn't set direction for gpio %d", gpio); perror("sysfsgpio: "); @@ -141,7 +154,15 @@ static int setup_sysfs_gpio(int gpio, int is_output, int init_high) } snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); - ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); + for (;;) { + ret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC); + if (ret >= 0 || errno != EACCES) + break; + gettimeofday(&now, NULL); + if (timeval_compare(&now, &timeout) >= 0) + break; + jtag_sleep(10000); + } if (ret < 0) { LOG_ERROR("Couldn't open value for gpio %d", gpio); perror("sysfsgpio: "); From e8d4074cf859328990f14a6c57a669f741cb83a2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 24 Jun 2019 23:44:00 +0200 Subject: [PATCH 048/354] target/armv4_5: use c99 array designator to init arm_core_regs[] During code analysis and development, counting again and again the lines to find the index of the register is a boring error-prone brain-damaging activity. Use the c99 syntax and add once forever the array designators to specify the index values. The code behavior is not changed. Change-Id: I2c70f70794475679efb91a8dfadc00f50715bd3f Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5256 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/target/armv4_5.c | 84 ++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 53a6b2229..7a72a0bf0 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -274,24 +274,24 @@ static const struct { * correspond to r0..r7, and the fifteenth to PC, so that callers * don't need to map them. */ - { .name = "r0", .cookie = 0, .mode = ARM_MODE_ANY, .gdb_index = 0, }, - { .name = "r1", .cookie = 1, .mode = ARM_MODE_ANY, .gdb_index = 1, }, - { .name = "r2", .cookie = 2, .mode = ARM_MODE_ANY, .gdb_index = 2, }, - { .name = "r3", .cookie = 3, .mode = ARM_MODE_ANY, .gdb_index = 3, }, - { .name = "r4", .cookie = 4, .mode = ARM_MODE_ANY, .gdb_index = 4, }, - { .name = "r5", .cookie = 5, .mode = ARM_MODE_ANY, .gdb_index = 5, }, - { .name = "r6", .cookie = 6, .mode = ARM_MODE_ANY, .gdb_index = 6, }, - { .name = "r7", .cookie = 7, .mode = ARM_MODE_ANY, .gdb_index = 7, }, + [0] = { .name = "r0", .cookie = 0, .mode = ARM_MODE_ANY, .gdb_index = 0, }, + [1] = { .name = "r1", .cookie = 1, .mode = ARM_MODE_ANY, .gdb_index = 1, }, + [2] = { .name = "r2", .cookie = 2, .mode = ARM_MODE_ANY, .gdb_index = 2, }, + [3] = { .name = "r3", .cookie = 3, .mode = ARM_MODE_ANY, .gdb_index = 3, }, + [4] = { .name = "r4", .cookie = 4, .mode = ARM_MODE_ANY, .gdb_index = 4, }, + [5] = { .name = "r5", .cookie = 5, .mode = ARM_MODE_ANY, .gdb_index = 5, }, + [6] = { .name = "r6", .cookie = 6, .mode = ARM_MODE_ANY, .gdb_index = 6, }, + [7] = { .name = "r7", .cookie = 7, .mode = ARM_MODE_ANY, .gdb_index = 7, }, /* NOTE: regs 8..12 might be shadowed by FIQ ... flagging * them as MODE_ANY creates special cases. (ANY means * "not mapped" elsewhere; here it's "everything but FIQ".) */ - { .name = "r8", .cookie = 8, .mode = ARM_MODE_ANY, .gdb_index = 8, }, - { .name = "r9", .cookie = 9, .mode = ARM_MODE_ANY, .gdb_index = 9, }, - { .name = "r10", .cookie = 10, .mode = ARM_MODE_ANY, .gdb_index = 10, }, - { .name = "r11", .cookie = 11, .mode = ARM_MODE_ANY, .gdb_index = 11, }, - { .name = "r12", .cookie = 12, .mode = ARM_MODE_ANY, .gdb_index = 12, }, + [8] = { .name = "r8", .cookie = 8, .mode = ARM_MODE_ANY, .gdb_index = 8, }, + [9] = { .name = "r9", .cookie = 9, .mode = ARM_MODE_ANY, .gdb_index = 9, }, + [10] = { .name = "r10", .cookie = 10, .mode = ARM_MODE_ANY, .gdb_index = 10, }, + [11] = { .name = "r11", .cookie = 11, .mode = ARM_MODE_ANY, .gdb_index = 11, }, + [12] = { .name = "r12", .cookie = 12, .mode = ARM_MODE_ANY, .gdb_index = 12, }, /* Historical GDB mapping of indices: * - 13-14 are sp and lr, but banked counterparts are used @@ -300,47 +300,47 @@ static const struct { */ /* NOTE all MODE_USR registers are equivalent to MODE_SYS ones */ - { .name = "sp_usr", .cookie = 13, .mode = ARM_MODE_USR, .gdb_index = 26, }, - { .name = "lr_usr", .cookie = 14, .mode = ARM_MODE_USR, .gdb_index = 27, }, + [13] = { .name = "sp_usr", .cookie = 13, .mode = ARM_MODE_USR, .gdb_index = 26, }, + [14] = { .name = "lr_usr", .cookie = 14, .mode = ARM_MODE_USR, .gdb_index = 27, }, /* guaranteed to be at index 15 */ - { .name = "pc", .cookie = 15, .mode = ARM_MODE_ANY, .gdb_index = 15, }, - { .name = "r8_fiq", .cookie = 8, .mode = ARM_MODE_FIQ, .gdb_index = 28, }, - { .name = "r9_fiq", .cookie = 9, .mode = ARM_MODE_FIQ, .gdb_index = 29, }, - { .name = "r10_fiq", .cookie = 10, .mode = ARM_MODE_FIQ, .gdb_index = 30, }, - { .name = "r11_fiq", .cookie = 11, .mode = ARM_MODE_FIQ, .gdb_index = 31, }, - { .name = "r12_fiq", .cookie = 12, .mode = ARM_MODE_FIQ, .gdb_index = 32, }, + [15] = { .name = "pc", .cookie = 15, .mode = ARM_MODE_ANY, .gdb_index = 15, }, + [16] = { .name = "r8_fiq", .cookie = 8, .mode = ARM_MODE_FIQ, .gdb_index = 28, }, + [17] = { .name = "r9_fiq", .cookie = 9, .mode = ARM_MODE_FIQ, .gdb_index = 29, }, + [18] = { .name = "r10_fiq", .cookie = 10, .mode = ARM_MODE_FIQ, .gdb_index = 30, }, + [19] = { .name = "r11_fiq", .cookie = 11, .mode = ARM_MODE_FIQ, .gdb_index = 31, }, + [20] = { .name = "r12_fiq", .cookie = 12, .mode = ARM_MODE_FIQ, .gdb_index = 32, }, - { .name = "sp_fiq", .cookie = 13, .mode = ARM_MODE_FIQ, .gdb_index = 33, }, - { .name = "lr_fiq", .cookie = 14, .mode = ARM_MODE_FIQ, .gdb_index = 34, }, + [21] = { .name = "sp_fiq", .cookie = 13, .mode = ARM_MODE_FIQ, .gdb_index = 33, }, + [22] = { .name = "lr_fiq", .cookie = 14, .mode = ARM_MODE_FIQ, .gdb_index = 34, }, - { .name = "sp_irq", .cookie = 13, .mode = ARM_MODE_IRQ, .gdb_index = 35, }, - { .name = "lr_irq", .cookie = 14, .mode = ARM_MODE_IRQ, .gdb_index = 36, }, + [23] = { .name = "sp_irq", .cookie = 13, .mode = ARM_MODE_IRQ, .gdb_index = 35, }, + [24] = { .name = "lr_irq", .cookie = 14, .mode = ARM_MODE_IRQ, .gdb_index = 36, }, - { .name = "sp_svc", .cookie = 13, .mode = ARM_MODE_SVC, .gdb_index = 37, }, - { .name = "lr_svc", .cookie = 14, .mode = ARM_MODE_SVC, .gdb_index = 38, }, + [25] = { .name = "sp_svc", .cookie = 13, .mode = ARM_MODE_SVC, .gdb_index = 37, }, + [26] = { .name = "lr_svc", .cookie = 14, .mode = ARM_MODE_SVC, .gdb_index = 38, }, - { .name = "sp_abt", .cookie = 13, .mode = ARM_MODE_ABT, .gdb_index = 39, }, - { .name = "lr_abt", .cookie = 14, .mode = ARM_MODE_ABT, .gdb_index = 40, }, + [27] = { .name = "sp_abt", .cookie = 13, .mode = ARM_MODE_ABT, .gdb_index = 39, }, + [28] = { .name = "lr_abt", .cookie = 14, .mode = ARM_MODE_ABT, .gdb_index = 40, }, - { .name = "sp_und", .cookie = 13, .mode = ARM_MODE_UND, .gdb_index = 41, }, - { .name = "lr_und", .cookie = 14, .mode = ARM_MODE_UND, .gdb_index = 42, }, + [29] = { .name = "sp_und", .cookie = 13, .mode = ARM_MODE_UND, .gdb_index = 41, }, + [30] = { .name = "lr_und", .cookie = 14, .mode = ARM_MODE_UND, .gdb_index = 42, }, - { .name = "cpsr", .cookie = 16, .mode = ARM_MODE_ANY, .gdb_index = 25, }, - { .name = "spsr_fiq", .cookie = 16, .mode = ARM_MODE_FIQ, .gdb_index = 43, }, - { .name = "spsr_irq", .cookie = 16, .mode = ARM_MODE_IRQ, .gdb_index = 44, }, - { .name = "spsr_svc", .cookie = 16, .mode = ARM_MODE_SVC, .gdb_index = 45, }, - { .name = "spsr_abt", .cookie = 16, .mode = ARM_MODE_ABT, .gdb_index = 46, }, - { .name = "spsr_und", .cookie = 16, .mode = ARM_MODE_UND, .gdb_index = 47, }, + [31] = { .name = "cpsr", .cookie = 16, .mode = ARM_MODE_ANY, .gdb_index = 25, }, + [32] = { .name = "spsr_fiq", .cookie = 16, .mode = ARM_MODE_FIQ, .gdb_index = 43, }, + [33] = { .name = "spsr_irq", .cookie = 16, .mode = ARM_MODE_IRQ, .gdb_index = 44, }, + [34] = { .name = "spsr_svc", .cookie = 16, .mode = ARM_MODE_SVC, .gdb_index = 45, }, + [35] = { .name = "spsr_abt", .cookie = 16, .mode = ARM_MODE_ABT, .gdb_index = 46, }, + [36] = { .name = "spsr_und", .cookie = 16, .mode = ARM_MODE_UND, .gdb_index = 47, }, /* These are only used for GDB target description, banked registers are accessed instead */ - { .name = "sp", .cookie = 13, .mode = ARM_MODE_ANY, .gdb_index = 13, }, - { .name = "lr", .cookie = 14, .mode = ARM_MODE_ANY, .gdb_index = 14, }, + [37] = { .name = "sp", .cookie = 13, .mode = ARM_MODE_ANY, .gdb_index = 13, }, + [38] = { .name = "lr", .cookie = 14, .mode = ARM_MODE_ANY, .gdb_index = 14, }, /* These exist only when the Security Extension (TrustZone) is present */ - { .name = "sp_mon", .cookie = 13, .mode = ARM_MODE_MON, .gdb_index = 48, }, - { .name = "lr_mon", .cookie = 14, .mode = ARM_MODE_MON, .gdb_index = 49, }, - { .name = "spsr_mon", .cookie = 16, .mode = ARM_MODE_MON, .gdb_index = 50, }, + [39] = { .name = "sp_mon", .cookie = 13, .mode = ARM_MODE_MON, .gdb_index = 48, }, + [40] = { .name = "lr_mon", .cookie = 14, .mode = ARM_MODE_MON, .gdb_index = 49, }, + [41] = { .name = "spsr_mon", .cookie = 16, .mode = ARM_MODE_MON, .gdb_index = 50, }, }; From 90bd7d148225efa587d8e62017625709a1ac002d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 7 Jun 2019 15:31:06 +0200 Subject: [PATCH 049/354] helper/command: remove unused field in struct command_registration The field jim_handler_data in struct command_registration is never assigned, thus has always value NULL. It was added in commit 17a9dea53a71 ("add jim_handler to command_registration") on Nov 23 2009, together with the homonym field jim_handler_data in struct command, but never used since then. Only the field jim_handler_data in struct command is used. Remove the field from struct command_registration and use NULL where it was referenced (or remove the assignment if the recipient is already zero, e.g. allocated with calloc()). Removing the field decreases the total size of OpenOCD binary by only 4944 byte on a 64 bit x86. Not a significant improvement from this point of view. Change-Id: I9f1d281e3de6b2eb398e2d883c5e9ff92628aecd Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5225 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/helper/command.c | 3 +-- src/helper/command.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index d969933e2..ec07a5fef 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -333,7 +333,6 @@ static struct command *command_new(struct command_context *cmd_ctx, c->parent = parent; c->handler = cr->handler; c->jim_handler = cr->jim_handler; - c->jim_handler_data = cr->jim_handler_data; c->mode = cr->mode; command_add_child(command_list_for_parent(cmd_ctx, parent), c); @@ -385,7 +384,7 @@ struct command *register_command(struct command_context *context, int retval = ERROR_OK; if (NULL != cr->jim_handler && NULL == parent) { retval = Jim_CreateCommand(context->interp, cr->name, - cr->jim_handler, cr->jim_handler_data, NULL); + cr->jim_handler, NULL, NULL); } else if (NULL != cr->handler || NULL != parent) retval = register_command_handler(context, command_root(c)); diff --git a/src/helper/command.h b/src/helper/command.h index 733ba42dd..672ccd02b 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -226,7 +226,6 @@ struct command_registration { const char *name; command_handler_t handler; Jim_CmdProc *jim_handler; - void *jim_handler_data; enum command_mode mode; const char *help; /** a string listing the options and arguments, required or optional */ From 2dc88e1479f29ef0141b05bfcd907ad9a3e2d54c Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Fri, 2 Dec 2016 15:39:23 +0100 Subject: [PATCH 050/354] target/armv7m_trace: Improve SWO frequency auto-detection The SWO frequency auto-detection with J-Link adapters does not work properly in the current implementation. This is because the trace layer has only information about the highest possible SWO frequency supported by the adapter. With that the trace layer calculates the SWO prescaler which usually leads to a frequency deviation greater than what is permitted by J-Link adapters. Move the calculation of the SWO prescaler from the trace layer into the trace configuration of the adapter to overcome this problem. The adapter has the necessary information to choose a suitable SWO frequency and calculate the corresponding prescaler that complies with the maximum allowed frequency deviation. Tested with: - STM32L152RC Discovery Kit (ST-Link) - EFM32GG-STK3700 (J-Link) Change-Id: I38ff2b89d32f0a92c597989b590afe5c75cf4902 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/3903 Tested-by: jenkins Reviewed-by: Paul Fertser --- src/jtag/core.c | 11 ++-- src/jtag/drivers/jlink.c | 106 ++++++++++++++++++++++++++-------- src/jtag/drivers/stlink_usb.c | 20 ++++++- src/jtag/hla/hla_interface.c | 7 ++- src/jtag/hla/hla_layout.h | 6 +- src/jtag/interface.h | 9 ++- src/target/armv7m_trace.c | 26 ++------- src/target/cortex_m.h | 3 + 8 files changed, 129 insertions(+), 59 deletions(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index 144cf94f7..a498a8cf4 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1918,12 +1918,13 @@ void adapter_deassert_reset(void) } int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq) + uint32_t port_size, unsigned int *trace_freq, + unsigned int traceclkin_freq, uint16_t *prescaler) { - if (jtag->config_trace) - return jtag->config_trace(enabled, pin_protocol, port_size, - trace_freq); - else if (enabled) { + if (jtag->config_trace) { + return jtag->config_trace(enabled, pin_protocol, port_size, trace_freq, + traceclkin_freq, prescaler); + } else if (enabled) { LOG_ERROR("The selected interface does not support tracing"); return ERROR_FAIL; } diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 09b3a858b..d2a871225 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -62,6 +63,9 @@ static bool trace_enabled; static unsigned int swd_buffer_size = JLINK_TAP_BUFFER_SIZE; +/* Maximum SWO frequency deviation. */ +#define SWO_MAX_FREQ_DEV 0.03 + /* 256 byte non-volatile memory */ struct device_config { uint8_t usb_address; @@ -1267,42 +1271,63 @@ static uint32_t calculate_trace_buffer_size(void) return tmp & 0xffffff00; } -static bool check_trace_freq(struct jaylink_swo_speed speed, - uint32_t trace_freq) +static bool calculate_swo_prescaler(unsigned int traceclkin_freq, + uint32_t trace_freq, uint16_t *prescaler) { - double min; + unsigned int presc; double deviation; + + presc = ((1.0 - SWO_MAX_FREQ_DEV) * traceclkin_freq) / trace_freq + 1; + + if (presc > TPIU_ACPR_MAX_SWOSCALER) + return false; + + deviation = fabs(1.0 - ((double)trace_freq * presc / traceclkin_freq)); + + if (deviation > SWO_MAX_FREQ_DEV) + return false; + + *prescaler = presc; + + return true; +} + +static bool detect_swo_freq_and_prescaler(struct jaylink_swo_speed speed, + unsigned int traceclkin_freq, uint32_t *trace_freq, + uint16_t *prescaler) +{ uint32_t divider; + unsigned int presc; + double deviation; - min = fabs(1.0 - (speed.freq / ((double)trace_freq * speed.min_div))); + for (divider = speed.min_div; divider <= speed.max_div; divider++) { + *trace_freq = speed.freq / divider; + presc = ((1.0 - SWO_MAX_FREQ_DEV) * traceclkin_freq) / *trace_freq + 1; - for (divider = speed.min_div; divider < speed.max_div; divider++) { - deviation = fabs(1.0 - (speed.freq / ((double)trace_freq * divider))); + if (presc > TPIU_ACPR_MAX_SWOSCALER) + break; - if (deviation < 0.03) { - LOG_DEBUG("Found suitable frequency divider %u with deviation of " - "%.02f %%.", divider, deviation); + deviation = fabs(1.0 - ((double)*trace_freq * presc / traceclkin_freq)); + + if (deviation <= SWO_MAX_FREQ_DEV) { + *prescaler = presc; return true; } - - if (deviation < min) - min = deviation; } - LOG_ERROR("Selected trace frequency is not supported by the device. " - "Please choose a different trace frequency."); - LOG_ERROR("Maximum permitted deviation is 3.00 %%, but only %.02f %% " - "could be achieved.", min * 100); - return false; } static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq) + uint32_t port_size, unsigned int *trace_freq, + unsigned int traceclkin_freq, uint16_t *prescaler) { int ret; uint32_t buffer_size; struct jaylink_swo_speed speed; + uint32_t divider; + uint32_t min_freq; + uint32_t max_freq; if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SWO)) { LOG_ERROR("Trace capturing is not supported by the device."); @@ -1349,13 +1374,45 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, return ERROR_FAIL; } - if (!*trace_freq) - *trace_freq = speed.freq / speed.min_div; + if (*trace_freq > 0) { + divider = speed.freq / *trace_freq; + min_freq = speed.freq / speed.max_div; + max_freq = speed.freq / speed.min_div; - if (!check_trace_freq(speed, *trace_freq)) - return ERROR_FAIL; + if (*trace_freq > max_freq) { + LOG_INFO("Given SWO frequency too high, using %u Hz instead.", + max_freq); + *trace_freq = max_freq; + } else if (*trace_freq < min_freq) { + LOG_INFO("Given SWO frequency too low, using %u Hz instead.", + min_freq); + *trace_freq = min_freq; + } else if (*trace_freq != speed.freq / divider) { + *trace_freq = speed.freq / divider; - LOG_DEBUG("Using %u bytes device memory for trace capturing.", buffer_size); + LOG_INFO("Given SWO frequency is not supported by the device, " + "using %u Hz instead.", *trace_freq); + } + + if (!calculate_swo_prescaler(traceclkin_freq, *trace_freq, + prescaler)) { + LOG_ERROR("SWO frequency is not suitable. Please choose a " + "different frequency or use auto-detection."); + return ERROR_FAIL; + } + } else { + LOG_INFO("Trying to auto-detect SWO frequency."); + + if (!detect_swo_freq_and_prescaler(speed, traceclkin_freq, trace_freq, + prescaler)) { + LOG_ERROR("Maximum permitted frequency deviation of %.02f %% " + "could not be achieved.", SWO_MAX_FREQ_DEV); + LOG_ERROR("Auto-detection of SWO frequency failed."); + return ERROR_FAIL; + } + + LOG_INFO("Using SWO frequency of %u Hz.", *trace_freq); + } ret = jaylink_swo_start(devh, JAYLINK_SWO_MODE_UART, *trace_freq, buffer_size); @@ -1365,6 +1422,9 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, return ERROR_FAIL; } + LOG_DEBUG("Using %u bytes device memory for trace capturing.", + buffer_size); + /* * Adjust the SWD transaction buffer size as starting SWO capturing * allocates device internal memory. diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 12e1175f5..a16810413 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -2883,10 +2883,13 @@ error_open: return ERROR_FAIL; } -int stlink_config_trace(void *handle, bool enabled, enum tpiu_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq) +int stlink_config_trace(void *handle, bool enabled, + enum tpiu_pin_protocol pin_protocol, uint32_t port_size, + unsigned int *trace_freq, unsigned int traceclkin_freq, + uint16_t *prescaler) { struct stlink_usb_handle_s *h = handle; + uint16_t presc; if (enabled && (!(h->version.flags & STLINK_F_HAS_TRACE) || pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART)) { @@ -2909,6 +2912,19 @@ int stlink_config_trace(void *handle, bool enabled, enum tpiu_pin_protocol pin_p if (!*trace_freq) *trace_freq = STLINK_TRACE_MAX_HZ; + + presc = traceclkin_freq / *trace_freq; + + if (traceclkin_freq % *trace_freq > 0) + presc++; + + if (presc > TPIU_ACPR_MAX_SWOSCALER) { + LOG_ERROR("SWO frequency is not suitable. Please choose a different " + "frequency."); + return ERROR_FAIL; + } + + *prescaler = presc; h->trace.source_hz = *trace_freq; return stlink_usb_trace_enable(h); diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index 2abed210d..7d9dea05e 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -192,11 +192,12 @@ int hl_interface_override_target(const char **targetname) } int hl_interface_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq) + uint32_t port_size, unsigned int *trace_freq, + unsigned int traceclkin_freq, uint16_t *prescaler) { if (hl_if.layout->api->config_trace) - return hl_if.layout->api->config_trace(hl_if.handle, enabled, pin_protocol, - port_size, trace_freq); + return hl_if.layout->api->config_trace(hl_if.handle, enabled, + pin_protocol, port_size, trace_freq, traceclkin_freq, prescaler); else if (enabled) { LOG_ERROR("The selected interface does not support tracing"); return ERROR_FAIL; diff --git a/src/jtag/hla/hla_layout.h b/src/jtag/hla/hla_layout.h index 9f41b59a4..1d759e17d 100644 --- a/src/jtag/hla/hla_layout.h +++ b/src/jtag/hla/hla_layout.h @@ -91,8 +91,10 @@ struct hl_layout_api_s { * its maximum supported rate there * @returns ERROR_OK on success, an error code on failure. */ - int (*config_trace)(void *handle, bool enabled, enum tpiu_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq); + int (*config_trace)(void *handle, bool enabled, + enum tpiu_pin_protocol pin_protocol, uint32_t port_size, + unsigned int *trace_freq, unsigned int traceclkin_freq, + uint16_t *prescaler); /** * Poll for new trace data * diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 905f1eb62..ba3dea6d7 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -303,10 +303,14 @@ struct jtag_interface { * @param trace_freq A pointer to the configured trace * frequency; if it points to 0, the adapter driver must write * its maximum supported rate there + * @param traceclkin_freq TRACECLKIN frequency provided to the TPIU in Hz + * @param prescaler Pointer to the SWO prescaler calculated by the + * adapter * @returns ERROR_OK on success, an error code on failure. */ int (*config_trace)(bool enabled, enum tpiu_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq); + uint32_t port_size, unsigned int *trace_freq, + unsigned int traceclkin_freq, uint16_t *prescaler); /** * Poll for new trace data @@ -325,7 +329,8 @@ extern const char * const jtag_only[]; void adapter_assert_reset(void); void adapter_deassert_reset(void); int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, - uint32_t port_size, unsigned int *trace_freq); + uint32_t port_size, unsigned int *trace_freq, + unsigned int traceclkin_freq, uint16_t *prescaler); int adapter_poll_trace(uint8_t *buf, size_t *size); #endif /* OPENOCD_JTAG_INTERFACE_H */ diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c index 6170119d9..853362f7e 100644 --- a/src/target/armv7m_trace.c +++ b/src/target/armv7m_trace.c @@ -56,16 +56,15 @@ int armv7m_trace_tpiu_config(struct target *target) { struct armv7m_common *armv7m = target_to_armv7m(target); struct armv7m_trace_config *trace_config = &armv7m->trace_config; - int prescaler; + uint16_t prescaler; int retval; target_unregister_timer_callback(armv7m_poll_trace, target); - retval = adapter_config_trace(trace_config->config_type == TRACE_CONFIG_TYPE_INTERNAL, - trace_config->pin_protocol, - trace_config->port_size, - &trace_config->trace_freq); + trace_config->pin_protocol, trace_config->port_size, + &trace_config->trace_freq, trace_config->traceclkin_freq, &prescaler); + if (retval != ERROR_OK) return retval; @@ -74,23 +73,6 @@ int armv7m_trace_tpiu_config(struct target *target) return ERROR_FAIL; } - prescaler = trace_config->traceclkin_freq / trace_config->trace_freq; - - if (trace_config->traceclkin_freq % trace_config->trace_freq) { - prescaler++; - int trace_freq = trace_config->traceclkin_freq / prescaler; - LOG_INFO("Can not obtain %u trace port frequency from %u TRACECLKIN frequency, using %u instead", - trace_config->trace_freq, trace_config->traceclkin_freq, - trace_freq); - trace_config->trace_freq = trace_freq; - retval = adapter_config_trace(trace_config->config_type == TRACE_CONFIG_TYPE_INTERNAL, - trace_config->pin_protocol, - trace_config->port_size, - &trace_config->trace_freq); - if (retval != ERROR_OK) - return retval; - } - retval = target_write_u32(target, TPIU_CSPSR, 1 << trace_config->port_size); if (retval != ERROR_OK) return retval; diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 54d7a0228..505a09b68 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -86,6 +86,9 @@ #define TPIU_FFCR 0xE0040304 #define TPIU_FSCR 0xE0040308 +/* Maximum SWO prescaler value. */ +#define TPIU_ACPR_MAX_SWOSCALER 0x1fff + /* DCB_DHCSR bit and field definitions */ #define DBGKEY (0xA05F << 16) #define C_DEBUGEN (1 << 0) From 9c5c3ab3d60285fb7976341031705d0340c5fe33 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Tue, 10 Sep 2019 03:32:36 +0800 Subject: [PATCH 051/354] tcl/target: swm050: fix to allow to use with ST-Link Currently the code assumes the adapter uses raw SWD, and the expected ID code of the CPU is even wrong. An adapter speed is also not specified. All these prevents the config file to be used with ST-Link. Fix the config file, to allow it to be used with ST-Link. Change-Id: I1244320fabfe8ee23da5a56a592dbeddc72cc8d5 Signed-off-by: Icenowy Zheng Reviewed-on: http://openocd.zylin.com/5297 Tested-by: jenkins Reviewed-by: Caleb Szalacinski Reviewed-by: Tomas Vanek --- tcl/target/swm050.cfg | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tcl/target/swm050.cfg b/tcl/target/swm050.cfg index a819f9c42..2c4ab34fe 100644 --- a/tcl/target/swm050.cfg +++ b/tcl/target/swm050.cfg @@ -1,5 +1,7 @@ # Synwit SWM050 +source [find target/swj-dp.tcl] + if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { @@ -16,10 +18,10 @@ if { [info exists WORKAREASIZE] } { if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID } else { - set _CPUTAPID 0x410CC200 + set _CPUTAPID 0x0bb11477 } -swd newdap $_CHIPNAME cpu -expected-id $_CPUTAPID +swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap @@ -27,6 +29,7 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME +adapter_khz 1000 $_TARGETNAME configure -event reset-init { # Stop the watchdog, just to be safe From bc0667c2371b7b142356aaab7f125c30f76168fd Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 16 Dec 2019 15:21:33 +0100 Subject: [PATCH 052/354] flash/nor/stm32h7: (minor) use proper variable names and enhance logging -fsize_base should be fsize_addr as it is the address of FLASH_SIZE register -flash_base should be flash_regs_base to avoid confusion with flash block start -add LOG_ERROR to functions stm32x_[read|write]_flash_reg(...) Change-Id: I86f035314bcd616fc0bdf445692d945a85c15481 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5362 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/stm32h7x.c | 55 +++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 736c8d2c4..008572915 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -117,15 +117,15 @@ struct stm32h7x_part_info { uint16_t max_flash_size_kb; uint8_t has_dual_bank; uint16_t first_bank_size_kb; /* Used when has_dual_bank is true */ - uint32_t flash_base; /* Flash controller registers location */ - uint32_t fsize_base; /* Location of FSIZE register */ + uint32_t flash_regs_base; /* Flash controller registers location */ + uint32_t fsize_addr; /* Location of FSIZE register */ }; struct stm32h7x_flash_bank { int probed; uint32_t idcode; uint32_t user_bank_size; - uint32_t flash_base; /* Address of flash reg controller */ + uint32_t flash_regs_base; /* Address of flash reg controller */ const struct stm32h7x_part_info *part_info; }; @@ -149,8 +149,8 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .max_flash_size_kb = 2048, .first_bank_size_kb = 1024, .has_dual_bank = 1, - .flash_base = FLASH_REG_BASE_B0, - .fsize_base = FLASH_SIZE_ADDRESS, + .flash_regs_base = FLASH_REG_BASE_B0, + .fsize_addr = FLASH_SIZE_ADDRESS, }, }; @@ -175,17 +175,29 @@ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) static inline uint32_t stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset) { struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; - return reg_offset + stm32x_info->flash_base; + return reg_offset + stm32x_info->flash_regs_base; } static inline int stm32x_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value) { - return target_read_u32(bank->target, stm32x_get_flash_reg(bank, reg_offset), value); + uint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset); + int retval = target_read_u32(bank->target, reg_addr, value); + + if (retval != ERROR_OK) + LOG_ERROR("error while reading from address 0x%" PRIx32, reg_addr); + + return retval; } static inline int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value) { - return target_write_u32(bank->target, stm32x_get_flash_reg(bank, reg_offset), value); + uint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset); + int retval = target_write_u32(bank->target, reg_addr, value); + + if (retval != ERROR_OK) + LOG_ERROR("error while writing to address 0x%" PRIx32, reg_addr); + + return retval; } static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status) @@ -195,30 +207,27 @@ static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *sta static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout) { - struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; uint32_t status; int retval; /* wait for flash operations completion */ for (;;) { retval = stm32x_get_flash_status(bank, &status); - if (retval != ERROR_OK) { - LOG_INFO("wait_flash_op_queue, target_read_u32 : error : remote address 0x%x", stm32x_info->flash_base); + if (retval != ERROR_OK) return retval; - } if ((status & FLASH_QW) == 0) break; if (timeout-- <= 0) { - LOG_INFO("wait_flash_op_queue, time out expired, status: 0x%" PRIx32 "", status); + LOG_ERROR("wait_flash_op_queue, time out expired, status: 0x%" PRIx32 "", status); return ERROR_FAIL; } alive_sleep(1); } if (status & FLASH_WRPERR) { - LOG_INFO("wait_flash_op_queue, WRPERR : error : remote address 0x%x", stm32x_info->flash_base); + LOG_ERROR("wait_flash_op_queue, WRPERR detected"); retval = ERROR_FAIL; } @@ -338,14 +347,14 @@ static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uin uint32_t status; retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_CUR, &status); if (retval != ERROR_OK) { - LOG_INFO("stm32x_options_program: failed to read FLASH_OPTSR_CUR"); + LOG_ERROR("stm32x_options_program: failed to read FLASH_OPTSR_CUR"); goto flash_options_lock; } if ((status & OPT_BSY) == 0) break; if (timeout-- <= 0) { - LOG_INFO("waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32 "", status); + LOG_ERROR("waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32 "", status); retval = ERROR_FAIL; goto flash_options_lock; } @@ -472,7 +481,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, int first, int last) /* apply WRPSN mask */ protection &= 0xff; - LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%x", protection); + LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%" PRIx32, protection); /* apply new option value */ return stm32x_write_option(bank, FLASH_WPSN_PRG, protection); @@ -528,7 +537,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, } } - LOG_DEBUG("target_alloc_working_area_try : buffer_size -> 0x%x", buffer_size); + LOG_DEBUG("target_alloc_working_area_try : buffer_size -> 0x%" PRIx32, buffer_size); armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; armv7m_info.core_mode = ARM_MODE_THREAD; @@ -543,7 +552,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); buf_set_u32(reg_params[2].value, 0, 32, address); buf_set_u32(reg_params[3].value, 0, 32, count); - buf_set_u32(reg_params[4].value, 0, 32, stm32x_info->flash_base); + buf_set_u32(reg_params[4].value, 0, 32, stm32x_info->flash_regs_base); retval = target_run_flash_async_algorithm(target, buffer, @@ -556,7 +565,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, &armv7m_info); if (retval == ERROR_FLASH_OPERATION_FAILED) { - LOG_INFO("error executing stm32h7x flash write algorithm"); + LOG_ERROR("error executing stm32h7x flash write algorithm"); uint32_t flash_sr = buf_get_u32(reg_params[0].value, 0, 32); @@ -730,10 +739,10 @@ static int stm32x_probe(struct flash_bank *bank) } /* update the address of controller from data base */ - stm32x_info->flash_base = stm32x_info->part_info->flash_base; + stm32x_info->flash_regs_base = stm32x_info->part_info->flash_regs_base; /* get flash size from target */ - retval = target_read_u16(target, stm32x_info->part_info->fsize_base, &flash_size_in_kb); + retval = target_read_u16(target, stm32x_info->part_info->fsize_addr, &flash_size_in_kb); if (retval != ERROR_OK) { /* read error when device has invalid value, set max flash size */ flash_size_in_kb = stm32x_info->part_info->max_flash_size_kb; @@ -751,7 +760,7 @@ static int stm32x_probe(struct flash_bank *bank) base_address = second_bank_base; flash_size_in_kb = flash_size_in_kb - stm32x_info->part_info->first_bank_size_kb; /* bank1 also uses a register offset */ - stm32x_info->flash_base = FLASH_REG_BASE_B1; + stm32x_info->flash_regs_base = FLASH_REG_BASE_B1; } else if (bank->base == base_address) { /* This is the first bank */ flash_size_in_kb = stm32x_info->part_info->first_bank_size_kb; From 0750a7c085b0fb8b195b210a6835c93ea88a19f3 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 16 Dec 2019 16:05:17 +0100 Subject: [PATCH 053/354] target/arm_cti: add new 'ack' and 'channel' commands these commands have been introduced to ease the manipulation of CTI trough script files, these commands are: - $cti_name ack $event : to acknowledge a CTI event - $cti_name channel $channel_number $operation: to perform an operation on a specific channel, the possible operations are: gate, ungate, set, clear and pulse Change-Id: I35463867a3c85072f3776c3aeb1e5788953ec435 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5315 Reviewed-by: Tomas Vanek Tested-by: jenkins --- doc/openocd.texi | 9 ++++++ src/target/arm_cti.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/doc/openocd.texi b/doc/openocd.texi index de7fe0ac1..349998b35 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -8436,6 +8436,15 @@ Write @var{value} to the CTI register with the symbolic name @var{reg_name}. Print the value read from the CTI register with the symbolic name @var{reg_name}. @end deffn +@deffn Command {$cti_name ack} @var{event} +Acknowledge a CTI @var{event}. +@end deffn + +@deffn Command {$cti_name channel} @var{channel_number} @var{operation} +Perform a specific channel operation, the possible operations are: +gate, ungate, set, clear and pulse +@end deffn + @deffn Command {$cti_name testmode} @option{on|off} Enable (@option{on}) or disable (@option{off}) the integration test mode of the CTI. diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c index 3f063b894..d415eb3a8 100644 --- a/src/target/arm_cti.c +++ b/src/target/arm_cti.c @@ -341,6 +341,59 @@ COMMAND_HANDLER(handle_cti_read) return ERROR_OK; } +COMMAND_HANDLER(handle_cti_ack) +{ + struct arm_cti_object *obj = CMD_DATA; + struct arm_cti *cti = &obj->cti; + uint32_t event; + + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], event); + + int retval = arm_cti_ack_events(cti, 1 << event); + + + if (retval != ERROR_OK) + return retval; + + return ERROR_OK; +} + +COMMAND_HANDLER(handle_cti_channel) +{ + struct arm_cti_object *obj = CMD_DATA; + struct arm_cti *cti = &obj->cti; + int retval = ERROR_OK; + uint32_t ch_num; + + if (CMD_ARGC != 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], ch_num); + + if (!strcmp(CMD_ARGV[1], "gate")) + retval = arm_cti_gate_channel(cti, ch_num); + else if (!strcmp(CMD_ARGV[1], "ungate")) + retval = arm_cti_ungate_channel(cti, ch_num); + else if (!strcmp(CMD_ARGV[1], "pulse")) + retval = arm_cti_pulse_channel(cti, ch_num); + else if (!strcmp(CMD_ARGV[1], "set")) + retval = arm_cti_set_channel(cti, ch_num); + else if (!strcmp(CMD_ARGV[1], "clear")) + retval = arm_cti_clear_channel(cti, ch_num); + else { + command_print(CMD, "Possible channel operations: gate|ungate|set|clear|pulse"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + if (retval != ERROR_OK) + return retval; + + return ERROR_OK; +} + static const struct command_registration cti_instance_command_handlers[] = { { .name = "dump", @@ -377,6 +430,21 @@ static const struct command_registration cti_instance_command_handlers[] = { .help = "read a CTI register", .usage = "register_name", }, + { + .name = "ack", + .mode = COMMAND_EXEC, + .handler = handle_cti_ack, + .help = "acknowledge a CTI event", + .usage = "event", + }, + { + .name = "channel", + .mode = COMMAND_EXEC, + .handler = handle_cti_channel, + .help = "do an operation on one CTI channel, possible operations: " + "gate, ungate, set, clear and pulse", + .usage = "channel_number operation", + }, COMMAND_REGISTRATION_DONE }; From bb1c7ae4ae23a507175e751c705ad543ea2e9953 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Tue, 10 Dec 2019 20:12:58 +0100 Subject: [PATCH 054/354] flash/nor/kinetis: fix clang static analyzer warnings Use assert to remove "Dereference of null pointer" warnings. Change-Id: Ie204c234a71758e6470351e1d9f22da3dd887f56 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5357 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/kinetis.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index 687a3370b..1d6335282 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -1443,6 +1443,8 @@ static int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf) kinetis_auto_probe(bank_iter); + assert(bank_iter->prot_blocks); + if (k_bank->flash_class == FC_PFLASH) { for (i = 0; i < bank_iter->num_prot_blocks; i++) { if (bank_iter->prot_blocks[i].is_protected == 1) @@ -2624,7 +2626,10 @@ static int kinetis_probe(struct flash_bank *bank) unsigned num_blocks, first_nvm_bank; uint32_t size_k; struct kinetis_flash_bank *k_bank = bank->driver_priv; - struct kinetis_chip *k_chip = k_bank->k_chip; + struct kinetis_chip *k_chip; + + assert(k_bank); + k_chip = k_bank->k_chip; k_bank->probed = false; From 6568d29cc1d0d94daafec5bdb73de7d4f17da257 Mon Sep 17 00:00:00 2001 From: Rahul Masurkar Date: Tue, 6 Aug 2019 18:19:07 +0530 Subject: [PATCH 055/354] rtos/FreeRTOS: Fix FreeRTOS thread list reading Change-Id: I749ae94ec7279907b1905c02ecc1e9661f43ef70 Signed-off-by: Rahul Masurkar Reviewed-on: http://openocd.zylin.com/5273 Tested-by: jenkins Reviewed-by: Karl Palsson Reviewed-by: Tomas Vanek --- src/rtos/FreeRTOS.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c index 9d89974cc..77c6e79d5 100644 --- a/src/rtos/FreeRTOS.c +++ b/src/rtos/FreeRTOS.c @@ -263,14 +263,14 @@ static int FreeRTOS_update_threads(struct rtos *rtos) symbol_address_t *list_of_lists = malloc(sizeof(symbol_address_t) * - (max_used_priority+1 + 5)); + (max_used_priority + 5)); if (!list_of_lists) { LOG_ERROR("Error allocating memory for %" PRId64 " priorities", max_used_priority); return ERROR_FAIL; } int num_lists; - for (num_lists = 0; num_lists <= max_used_priority; num_lists++) + for (num_lists = 0; num_lists < max_used_priority; num_lists++) list_of_lists[num_lists] = rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address + num_lists * param->list_width; From 223c28f9b9f685c98fb6882e1657b6b53379a1a6 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Mon, 20 May 2019 18:14:46 +0200 Subject: [PATCH 056/354] contrib/rpc_examples: Add (dis)connect methods Add these methods such that the OpenOcd class can also be used outside of a 'with' statement. Change-Id: I927c93fff2dc05cc74daa56360a7262e736a639f Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5189 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- contrib/rpc_examples/ocd_rpc_example.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/contrib/rpc_examples/ocd_rpc_example.py b/contrib/rpc_examples/ocd_rpc_example.py index 4b1516ad9..9d17e7695 100755 --- a/contrib/rpc_examples/ocd_rpc_example.py +++ b/contrib/rpc_examples/ocd_rpc_example.py @@ -49,10 +49,16 @@ class OpenOcd: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) def __enter__(self): - self.sock.connect((self.tclRpcIp, self.tclRpcPort)) + self.connect() return self def __exit__(self, type, value, traceback): + self.disconnect() + + def connect(self): + self.sock.connect((self.tclRpcIp, self.tclRpcPort)) + + def disconnect(self): try: self.send("exit") finally: From 7f5caa24e3bc8d8563d23463b4c8f1ea746262e0 Mon Sep 17 00:00:00 2001 From: Oleksandr Redchuk Date: Sat, 23 Feb 2019 23:03:13 +0200 Subject: [PATCH 057/354] flash/nor/stm32f1x: fix options reading from locked chip In commit cea40152f82f52bfc718c7bda9fa4a9d70bf9cfd option bytes reading was changed to direct access to option bytes area. While there are no problems with stm32f0xx and stm32f3xx chips, option block (0x1ffff800..0x1ffff80F) is unreadable from locked stm32f10x chips. As a result, stm32f1x unlock command writes dirty values to user options, user data and write protection bits. Option bytes reading reverted from direct access to option bytes area to reading currently loaded bytes from FLASH_OBR/FLASH_WRPR registers. Tested on stm32f100, stm32f103, stm32f107 as well as on stm32f030 and stm32f303. Change-Id: Iad476351ffdaca5ace12e02272dacea7f3d08f52 Signed-off-by: Oleksandr Redchuk Reviewed-on: http://openocd.zylin.com/4940 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/stm32f1x.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index cf10e3747..91fd541f6 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -229,34 +229,20 @@ static int stm32x_read_options(struct flash_bank *bank) uint32_t option_bytes; int retval; - /* read user and read protection option bytes */ - retval = target_read_u32(target, STM32_OB_RDP, &option_bytes); + /* read user and read protection option bytes, user data option bytes */ + retval = target_read_u32(target, STM32_FLASH_OBR_B0, &option_bytes); if (retval != ERROR_OK) return retval; - stm32x_info->option_bytes.rdp = option_bytes & 0xFF; - stm32x_info->option_bytes.user = (option_bytes >> 16) & 0xFF; - - /* read user data option bytes */ - retval = target_read_u32(target, STM32_OB_DATA0, &option_bytes); - if (retval != ERROR_OK) - return retval; - - stm32x_info->option_bytes.data = ((option_bytes >> 8) & 0xFF00) | (option_bytes & 0xFF); + stm32x_info->option_bytes.rdp = (option_bytes & (1 << OPT_READOUT)) ? 0 : stm32x_info->default_rdp; + stm32x_info->option_bytes.user = (option_bytes >> stm32x_info->option_offset >> 2) & 0xff; + stm32x_info->option_bytes.data = (option_bytes >> stm32x_info->user_data_offset) & 0xffff; /* read write protection option bytes */ - retval = target_read_u32(target, STM32_OB_WRP0, &option_bytes); + retval = target_read_u32(target, STM32_FLASH_WRPR_B0, &stm32x_info->option_bytes.protection); if (retval != ERROR_OK) return retval; - stm32x_info->option_bytes.protection = ((option_bytes >> 8) & 0xFF00) | (option_bytes & 0xFF); - - retval = target_read_u32(target, STM32_OB_WRP2, &option_bytes); - if (retval != ERROR_OK) - return retval; - - stm32x_info->option_bytes.protection |= (((option_bytes >> 8) & 0xFF00) | (option_bytes & 0xFF)) << 16; - return ERROR_OK; } From deff24afa13fe5188c207258d6d1935bc3dd0870 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Mon, 21 Oct 2019 08:44:08 +0200 Subject: [PATCH 058/354] jtag_vpi: multiple improvements - Fix: Proper handling of read_socket() and write_socket() in case of "partial" read/write. - Added low-level JTAG IO debug capability (_DEBUG_JTAG_IO_) - Zero-fill packet buffers, avoid sending pieces of uninitialized memory over the network (memset struct vpi_cmd) - Use close_socket() instead of close() - needed for Win32 - Fixed usage messages of jtag_vpi_command_handlers Change-Id: I8bd19bc5c9512fe8e798600212e8a95213f50f5b Signed-off-by: Jan Matyas Reviewed-on: http://openocd.zylin.com/5177 Tested-by: jenkins Reviewed-by: Andreas Fritiofson Reviewed-by: Tomas Vanek --- src/helper/log.c | 25 +++++++ src/helper/log.h | 2 + src/jtag/drivers/jtag_vpi.c | 133 +++++++++++++++++++++++++++++++++--- 3 files changed, 151 insertions(+), 9 deletions(-) diff --git a/src/helper/log.c b/src/helper/log.c index d65430c50..8f48b928b 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -454,3 +454,28 @@ void busy_sleep(uint64_t ms) */ } } + +/* Maximum size of socket error message retreived from operation system */ +#define MAX_SOCKET_ERR_MSG_LENGTH 256 + +/* Provide log message for the last socket error. + Uses errno on *nix and WSAGetLastError() on Windows */ +void log_socket_error(const char *socket_desc) +{ + int error_code; +#ifdef _WIN32 + error_code = WSAGetLastError(); + char error_message[MAX_SOCKET_ERR_MSG_LENGTH]; + error_message[0] = '\0'; + DWORD retval = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, 0, + error_message, MAX_SOCKET_ERR_MSG_LENGTH, NULL); + error_message[MAX_SOCKET_ERR_MSG_LENGTH - 1] = '\0'; + const bool have_message = (retval != 0) && (error_message[0] != '\0'); + LOG_ERROR("Error on socket '%s': WSAGetLastError==%d%s%s.", socket_desc, error_code, + (have_message ? ", message: " : ""), + (have_message ? error_message : "")); +#else + error_code = errno; + LOG_ERROR("Error on socket '%s': errno==%d, message: %s.", socket_desc, error_code, strerror(error_code)); +#endif +} diff --git a/src/helper/log.h b/src/helper/log.h index bc08fe49a..eac535deb 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -82,6 +82,8 @@ void kept_alive(void); void alive_sleep(uint64_t ms); void busy_sleep(uint64_t ms); +void log_socket_error(const char *socket_desc); + typedef void (*log_callback_fn)(void *priv, const char *file, unsigned line, const char *function, const char *string); diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c index 27b9da116..7ac7e962f 100644 --- a/src/jtag/drivers/jtag_vpi.c +++ b/src/jtag/drivers/jtag_vpi.c @@ -33,6 +33,8 @@ #include #endif +#include + #define NO_TAP_SHIFT 0 #define TAP_SHIFT 1 @@ -71,8 +73,58 @@ struct vpi_cmd { }; }; +static char *jtag_vpi_cmd_to_str(int cmd_num) +{ + switch (cmd_num) { + case CMD_RESET: + return "CMD_RESET"; + case CMD_TMS_SEQ: + return "CMD_TMS_SEQ"; + case CMD_SCAN_CHAIN: + return "CMD_SCAN_CHAIN"; + case CMD_SCAN_CHAIN_FLIP_TMS: + return "CMD_SCAN_CHAIN_FLIP_TMS"; + case CMD_STOP_SIMU: + return "CMD_STOP_SIMU"; + default: + return ""; + } +} + static int jtag_vpi_send_cmd(struct vpi_cmd *vpi) { + int retval; + + /* Optional low-level JTAG debug */ + if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) { + if (vpi->nb_bits > 0) { + /* command with a non-empty data payload */ + char *char_buf = buf_to_str(vpi->buffer_out, + (vpi->nb_bits > DEBUG_JTAG_IOZ) + ? DEBUG_JTAG_IOZ + : vpi->nb_bits, + 16); + LOG_DEBUG_IO("sending JTAG VPI cmd: cmd=%s, " + "length=%" PRIu32 ", " + "nb_bits=%" PRIu32 ", " + "buf_out=0x%s%s", + jtag_vpi_cmd_to_str(vpi->cmd), + vpi->length, + vpi->nb_bits, + char_buf, + (vpi->nb_bits > DEBUG_JTAG_IOZ) ? "(...)" : ""); + free(char_buf); + } else { + /* command without data payload */ + LOG_DEBUG_IO("sending JTAG VPI cmd: cmd=%s, " + "length=%" PRIu32 ", " + "nb_bits=%" PRIu32, + jtag_vpi_cmd_to_str(vpi->cmd), + vpi->length, + vpi->nb_bits); + } + } + /* Use little endian when transmitting/receiving jtag_vpi cmds. The choice of little endian goes against usual networking conventions but is intentional to remain compatible with most older OpenOCD builds @@ -81,18 +133,67 @@ static int jtag_vpi_send_cmd(struct vpi_cmd *vpi) h_u32_to_le(vpi->length_buf, vpi->length); h_u32_to_le(vpi->nb_bits_buf, vpi->nb_bits); - int retval = write_socket(sockfd, vpi, sizeof(struct vpi_cmd)); - if (retval <= 0) - return ERROR_FAIL; +retry_write: + retval = write_socket(sockfd, vpi, sizeof(struct vpi_cmd)); + if (retval < 0) { + /* Account for the case when socket write is interrupted. */ +#ifdef _WIN32 + int wsa_err = WSAGetLastError(); + if (wsa_err == WSAEINTR) + goto retry_write; +#else + if (errno == EINTR) + goto retry_write; +#endif + /* Otherwise this is an error using the socket, most likely fatal + for the connection. B*/ + log_socket_error("jtag_vpi xmit"); + /* TODO: Clean way how adapter drivers can report fatal errors + to upper layers of OpenOCD and let it perform an orderly shutdown? */ + exit(-1); + } else if (retval < (int)sizeof(struct vpi_cmd)) { + /* This means we could not send all data, which is most likely fatal + for the jtag_vpi connection (the underlying TCP connection likely not + usable anymore) */ + LOG_ERROR("Could not send all data through jtag_vpi connection."); + exit(-1); + } + + /* Otherwise the packet has been sent successfully. */ return ERROR_OK; } static int jtag_vpi_receive_cmd(struct vpi_cmd *vpi) { - int retval = read_socket(sockfd, vpi, sizeof(struct vpi_cmd)); - if (retval < (int)sizeof(struct vpi_cmd)) - return ERROR_FAIL; + unsigned bytes_buffered = 0; + while (bytes_buffered < sizeof(struct vpi_cmd)) { + int bytes_to_receive = sizeof(struct vpi_cmd) - bytes_buffered; + int retval = read_socket(sockfd, ((char *)vpi) + bytes_buffered, bytes_to_receive); + if (retval < 0) { +#ifdef _WIN32 + int wsa_err = WSAGetLastError(); + if (wsa_err == WSAEINTR) { + /* socket read interrupted by WSACancelBlockingCall() */ + continue; + } +#else + if (errno == EINTR) { + /* socket read interrupted by a signal */ + continue; + } +#endif + /* Otherwise, this is an error when accessing the socket. */ + log_socket_error("jtag_vpi recv"); + exit(-1); + } else if (retval == 0) { + /* Connection closed by the other side */ + LOG_ERROR("Connection prematurely closed by jtag_vpi server."); + exit(-1); + } + /* Otherwise, we have successfully received some data */ + bytes_buffered += retval; + } /* Use little endian when transmitting/receiving jtag_vpi cmds. */ vpi->cmd = le_to_h_u32(vpi->cmd_buf); @@ -110,6 +211,7 @@ static int jtag_vpi_receive_cmd(struct vpi_cmd *vpi) static int jtag_vpi_reset(int trst, int srst) { struct vpi_cmd vpi; + memset(&vpi, 0, sizeof(struct vpi_cmd)); vpi.cmd = CMD_RESET; vpi.length = 0; @@ -132,6 +234,7 @@ static int jtag_vpi_tms_seq(const uint8_t *bits, int nb_bits) struct vpi_cmd vpi; int nb_bytes; + memset(&vpi, 0, sizeof(struct vpi_cmd)); nb_bytes = DIV_ROUND_UP(nb_bits, 8); vpi.cmd = CMD_TMS_SEQ; @@ -199,6 +302,8 @@ static int jtag_vpi_queue_tdi_xfer(uint8_t *bits, int nb_bits, int tap_shift) struct vpi_cmd vpi; int nb_bytes = DIV_ROUND_UP(nb_bits, 8); + memset(&vpi, 0, sizeof(struct vpi_cmd)); + vpi.cmd = tap_shift ? CMD_SCAN_CHAIN_FLIP_TMS : CMD_SCAN_CHAIN; if (bits) @@ -217,6 +322,16 @@ static int jtag_vpi_queue_tdi_xfer(uint8_t *bits, int nb_bits, int tap_shift) if (retval != ERROR_OK) return retval; + /* Optional low-level JTAG debug */ + if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) { + char *char_buf = buf_to_str(vpi.buffer_in, + (nb_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : nb_bits, + 16); + LOG_DEBUG_IO("recvd JTAG VPI data: nb_bits=%d, buf_in=0x%s%s", + nb_bits, char_buf, (nb_bits > DEBUG_JTAG_IOZ) ? "(...)" : ""); + free(char_buf); + } + if (bits) memcpy(bits, vpi.buffer_in, nb_bytes); @@ -464,7 +579,7 @@ static int jtag_vpi_init(void) static int jtag_vpi_quit(void) { free(server_address); - return close(sockfd); + return close_socket(sockfd); } COMMAND_HANDLER(jtag_vpi_set_port) @@ -500,14 +615,14 @@ static const struct command_registration jtag_vpi_command_handlers[] = { .handler = &jtag_vpi_set_port, .mode = COMMAND_CONFIG, .help = "set the port of the VPI server", - .usage = "description_string", + .usage = "tcp_port_num", }, { .name = "jtag_vpi_set_address", .handler = &jtag_vpi_set_address, .mode = COMMAND_CONFIG, .help = "set the address of the VPI server", - .usage = "description_string", + .usage = "ipv4_addr", }, COMMAND_REGISTRATION_DONE }; From fafe6dfc9cd882f5cee4f4fa2b3971991d9e97b9 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 10 Jan 2019 10:58:15 +0100 Subject: [PATCH 059/354] adapter: add command "adapter [de]assert srst|trst [[de]assert srst|trst]" Inspired from http://openocd.zylin.com/#/c/3720/1 Add commands to control the adapter's signals srst and trst. Add macros for the flag's values assert/deassert to make clear what they mean and to propose a uniform set of values across the code. Change-Id: Ia8b13f4ded892942916cad7bda49540a896e7218 Signed-off-by: Antonio Borneo Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5277 Tested-by: jenkins --- src/jtag/adapter.c | 100 +++++++++++++++++++++++++++++++++++ src/jtag/core.c | 53 +++++++++++++++++++ src/jtag/hla/hla_interface.c | 15 ++++++ src/jtag/hla/hla_interface.h | 9 ++++ src/jtag/interface.h | 1 + src/jtag/jtag.h | 8 +++ 6 files changed, 186 insertions(+) diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index 29a961338..d23f79ec4 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -411,6 +411,92 @@ COMMAND_HANDLER(handle_adapter_khz_command) return retval; } +COMMAND_HANDLER(handle_adapter_reset_de_assert) +{ + enum values { + VALUE_UNDEFINED = -1, + VALUE_DEASSERT = 0, + VALUE_ASSERT = 1, + }; + enum values value; + enum values srst = VALUE_UNDEFINED; + enum values trst = VALUE_UNDEFINED; + enum reset_types jtag_reset_config = jtag_get_reset_config(); + char *signal; + + if (CMD_ARGC == 0) { + if (transport_is_jtag()) { + if (jtag_reset_config & RESET_HAS_TRST) + signal = jtag_get_trst() ? "asserted" : "deasserted"; + else + signal = "not present"; + command_print(CMD, "trst %s", signal); + } + + if (jtag_reset_config & RESET_HAS_SRST) + signal = jtag_get_srst() ? "asserted" : "deasserted"; + else + signal = "not present"; + command_print(CMD, "srst %s", signal); + + return ERROR_OK; + } + + if (CMD_ARGC != 1 && CMD_ARGC != 3) + return ERROR_COMMAND_SYNTAX_ERROR; + + value = (strcmp(CMD_NAME, "assert") == 0) ? VALUE_ASSERT : VALUE_DEASSERT; + if (strcmp(CMD_ARGV[0], "srst") == 0) + srst = value; + else if (strcmp(CMD_ARGV[0], "trst") == 0) + trst = value; + else + return ERROR_COMMAND_SYNTAX_ERROR; + + if (CMD_ARGC == 3) { + if (strcmp(CMD_ARGV[1], "assert") == 0) + value = VALUE_ASSERT; + else if (strcmp(CMD_ARGV[1], "deassert") == 0) + value = VALUE_DEASSERT; + else + return ERROR_COMMAND_SYNTAX_ERROR; + + if (strcmp(CMD_ARGV[2], "srst") == 0 && srst == VALUE_UNDEFINED) + srst = value; + else if (strcmp(CMD_ARGV[2], "trst") == 0 && trst == VALUE_UNDEFINED) + trst = value; + else + return ERROR_COMMAND_SYNTAX_ERROR; + } + + if (trst == VALUE_UNDEFINED) { + if (transport_is_jtag()) + trst = jtag_get_trst() ? VALUE_ASSERT : VALUE_DEASSERT; + else + trst = VALUE_DEASSERT; /* unused, safe value */ + } + + if (srst == VALUE_UNDEFINED) { + if (jtag_reset_config & RESET_HAS_SRST) + srst = jtag_get_srst() ? VALUE_ASSERT : VALUE_DEASSERT; + else + srst = VALUE_DEASSERT; /* unused, safe value */ + } + + if (trst == VALUE_ASSERT && !transport_is_jtag()) { + LOG_ERROR("transport has no trst signal"); + return ERROR_FAIL; + } + + if (srst == VALUE_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("adapter has no srst signal"); + return ERROR_FAIL; + } + + return adapter_resets((trst == VALUE_DEASSERT) ? TRST_DEASSERT : TRST_ASSERT, + (srst == VALUE_DEASSERT) ? SRST_DEASSERT : SRST_ASSERT); +} + #ifndef HAVE_JTAG_MINIDRIVER_H #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS COMMAND_HANDLER(handle_usb_location_command) @@ -448,6 +534,20 @@ static const struct command_registration adapter_command_handlers[] = { .chain = adapter_usb_command_handlers, }, #endif /* MINIDRIVER */ + { + .name = "assert", + .handler = handle_adapter_reset_de_assert, + .mode = COMMAND_EXEC, + .help = "Controls SRST and TRST lines.", + .usage = "|deassert [srst|trst [assert|deassert srst|trst]]", + }, + { + .name = "deassert", + .handler = handle_adapter_reset_de_assert, + .mode = COMMAND_EXEC, + .help = "Controls SRST and TRST lines.", + .usage = "|assert [srst|trst [deassert|assert srst|trst]]", + }, COMMAND_REGISTRATION_DONE }; diff --git a/src/jtag/core.c b/src/jtag/core.c index a498a8cf4..871b4d2bd 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -35,6 +35,8 @@ #include "interface.h" #include #include +#include +#include #ifdef HAVE_STRINGS_H #include @@ -1888,6 +1890,57 @@ bool transport_is_jtag(void) return get_current_transport() == &jtag_transport; } +int adapter_resets(int trst, int srst) +{ + if (get_current_transport() == NULL) { + LOG_ERROR("transport is not selected"); + return ERROR_FAIL; + } + + if (transport_is_jtag()) { + if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("adapter has no srst signal"); + return ERROR_FAIL; + } + + /* adapters without trst signal will eventually use tlr sequence */ + jtag_add_reset(trst, srst); + return ERROR_OK; + } else if (transport_is_swd()) { + if (trst == TRST_ASSERT) { + LOG_ERROR("transport swd has no trst signal"); + return ERROR_FAIL; + } + + if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("adapter has no srst signal"); + return ERROR_FAIL; + } + swd_add_reset(srst); + return ERROR_OK; + } else if (transport_is_hla()) { + if (trst == TRST_ASSERT) { + LOG_ERROR("transport %s has no trst signal", + get_current_transport()->name); + return ERROR_FAIL; + } + + if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("adapter has no srst signal"); + return ERROR_FAIL; + } + return hl_interface_reset(srst); + } + + if (trst == TRST_DEASSERT && srst == SRST_DEASSERT) + return ERROR_OK; + + LOG_ERROR("reset is not supported on transport %s", + get_current_transport()->name); + + return ERROR_FAIL; +} + void adapter_assert_reset(void) { if (transport_is_jtag()) { diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index 7d9dea05e..b50cb9c0f 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -148,6 +148,21 @@ int hl_interface_init_reset(void) return ERROR_OK; } +/* FIXME: hla abuses of jtag_add_reset() to track srst status and for timings */ +int hl_interface_reset(int srst) +{ + int result; + + if (srst == 1) { + jtag_add_reset(0, 1); + result = hl_if.layout->api->assert_srst(hl_if.handle, 0); + } else { + result = hl_if.layout->api->assert_srst(hl_if.handle, 1); + jtag_add_reset(0, 0); + } + return result; +} + static int hl_interface_khz(int khz, int *jtag_speed) { if (hl_if.layout->api->speed == NULL) diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h index 262025e98..84b0098b6 100644 --- a/src/jtag/hla/hla_interface.h +++ b/src/jtag/hla/hla_interface.h @@ -67,4 +67,13 @@ int hl_interface_init_target(struct target *t); int hl_interface_init_reset(void); int hl_interface_override_target(const char **targetname); +#if BUILD_HLADAPTER == 1 +int hl_interface_reset(int srst); +#else +static inline int hl_interface_reset(int srst) +{ + return ERROR_OK; +} +#endif + #endif /* OPENOCD_JTAG_HLA_HLA_INTERFACE_H */ diff --git a/src/jtag/interface.h b/src/jtag/interface.h index ba3dea6d7..410eef980 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -326,6 +326,7 @@ struct jtag_interface { extern const char * const jtag_only[]; +int adapter_resets(int assert_trst, int assert_srst); void adapter_assert_reset(void); void adapter_deassert_reset(void); int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index c93243c47..ff1783158 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -76,6 +76,14 @@ typedef enum tap_state { #endif } tap_state_t; +/** + * Defines arguments for reset functions + */ +#define SRST_DEASSERT 0 +#define SRST_ASSERT 1 +#define TRST_DEASSERT 0 +#define TRST_ASSERT 1 + /** * Function tap_state_name * Returns a string suitable for display representing the JTAG tap_state From c07b774e8f490984f749c2693f83483af7c0d098 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 14 Aug 2019 14:51:06 +0200 Subject: [PATCH 060/354] jtag: replace command "jtag_reset" with "adapter [de]assert" Replace the JTAG transport specific command with a more generic one. Deprecate "jtag_reset" and update the documentation. While there, fix an error in the documentation, where the command "jtag_reset" was used in place of command "reset_config". Change-Id: I41a988d37ce69f7b35a960cbaf5306aab0299b99 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5286 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 61 +++++++++++++++++++++++++------------------- src/jtag/startup.tcl | 16 ++++++++++++ src/jtag/tcl.c | 36 -------------------------- 3 files changed, 51 insertions(+), 62 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 349998b35..5da0f806b 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3599,7 +3599,8 @@ the @command{reset_config} mechanism doesn't address; or asserting both might trigger a stronger reset, which needs special attention. -Experiment with lower level operations, such as @command{jtag_reset} +Experiment with lower level operations, such as +@command{adapter assert}, @command{adapter deassert} and the @command{jtag arp_*} operations shown here, to find a sequence of operations that works. @xref{JTAG Commands}. @@ -3626,7 +3627,7 @@ or potentially some other value. The default implementation just invokes @command{jtag arp_init-reset}. Replacements will normally build on low level JTAG -operations such as @command{jtag_reset}. +operations such as @command{adapter assert} and @command{adapter deassert}. Operations here must not address individual TAPs (or their associated targets) until the JTAG scan chain has first been verified to work. @@ -6984,7 +6985,7 @@ configured for flash bank 0. @example # assert srst, we do not want core running # while accessing str9xpec flash driver -jtag_reset 0 1 +adapter assert srst # turn off target polling poll off # disable str9 core @@ -7885,6 +7886,36 @@ the code that was executed may have left the hardware in an unknown state. @end deffn +@deffn Command {adapter assert} [signal [assert|deassert signal]] +@deffnx Command {adapter deassert} [signal [assert|deassert signal]] +Set values of reset signals. +Without parameters returns current status of the signals. +The @var{signal} parameter values may be +@option{srst}, indicating that srst signal is to be asserted or deasserted, +@option{trst}, indicating that trst signal is to be asserted or deasserted. + +The @command{reset_config} command should already have been used +to configure how the board and the adapter treat these two +signals, and to say if either signal is even present. +@xref{Reset Configuration}. +Trying to assert a signal that is not present triggers an error. +If a signal is present on the adapter and not specified in the command, +the signal will not be modified. + +@quotation Note +TRST is specially handled. +It actually signifies JTAG's @sc{reset} state. +So if the board doesn't support the optional TRST signal, +or it doesn't support it along with the specified SRST value, +JTAG reset is triggered with TMS and TCK signals +instead of the TRST signal. +And no matter how that JTAG reset is triggered, once +the scan chain enters @sc{reset} with TRST inactive, +TAP @code{post-reset} events are delivered to all TAPs +with handlers for that event. +@end quotation +@end deffn + @section I/O Utilities These commands are available when @@ -9767,28 +9798,6 @@ portable scripts currently must issue only BYPASS instructions. @end quotation @end deffn -@deffn Command {jtag_reset} trst srst -Set values of reset signals. -The @var{trst} and @var{srst} parameter values may be -@option{0}, indicating that reset is inactive (pulled or driven high), -or @option{1}, indicating it is active (pulled or driven low). -The @command{reset_config} command should already have been used -to configure how the board and JTAG adapter treat these two -signals, and to say if either signal is even present. -@xref{Reset Configuration}. - -Note that TRST is specially handled. -It actually signifies JTAG's @sc{reset} state. -So if the board doesn't support the optional TRST signal, -or it doesn't support it along with the specified SRST value, -JTAG reset is triggered with TMS and TCK signals -instead of the TRST signal. -And no matter how that JTAG reset is triggered, once -the scan chain enters @sc{reset} with TRST inactive, -TAP @code{post-reset} events are delivered to all TAPs -with handlers for that event. -@end deffn - @deffn Command {pathmove} start_state [next_state ...] Start by moving to @var{start_state}, which must be one of the @emph{stable} states. @@ -10756,7 +10765,7 @@ bytes. Painful... "Warning: arm7_9_common.c:679 arm7_9_assert_reset(): srst resets test logic, too". This warning doesn't indicate any serious problem, as long as you don't want to -debug your core right out of reset. Your .cfg file specified @option{jtag_reset +debug your core right out of reset. Your .cfg file specified @option{reset_config trst_and_srst srst_pulls_trst} to tell OpenOCD that either your board, your debugger or your target uC (e.g. LPC2000) can't assert the two reset signals independently. With this setup, it's not possible to halt the core right out of diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index d57cafb23..355152136 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -134,6 +134,22 @@ proc jtag_nsrst_assert_width args { eval adapter_nsrst_assert_width $args } +proc jtag_reset args { + echo "DEPRECATED! use 'adapter [de]assert' not 'jtag_reset'" + switch $args { + "0 0" + {eval adapter deassert trst deassert srst} + "0 1" + {eval adapter deassert trst assert srst} + "1 0" + {eval adapter assert trst deassert srst} + "1 1" + {eval adapter assert trst assert srst} + default + {return -code 1 -level 1 "jtag_reset: syntax error"} + } +} + # stlink migration helpers proc stlink_device_desc args { echo "DEPRECATED! use 'hla_device_desc' not 'stlink_device_desc'" diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index cbdf2adfc..ef0cd3f53 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -1059,34 +1059,6 @@ COMMAND_HANDLER(handle_jtag_rclk_command) return retval; } -COMMAND_HANDLER(handle_jtag_reset_command) -{ - if (CMD_ARGC != 2) - return ERROR_COMMAND_SYNTAX_ERROR; - - int trst = -1; - if (CMD_ARGV[0][0] == '1') - trst = 1; - else if (CMD_ARGV[0][0] == '0') - trst = 0; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - int srst = -1; - if (CMD_ARGV[1][0] == '1') - srst = 1; - else if (CMD_ARGV[1][0] == '0') - srst = 0; - else - return ERROR_COMMAND_SYNTAX_ERROR; - - if (adapter_init(CMD_CTX) != ERROR_OK) - return ERROR_JTAG_INIT_FAILED; - - jtag_add_reset(trst, srst); - return jtag_execute_queue(); -} - COMMAND_HANDLER(handle_runtest_command) { if (CMD_ARGC != 1) @@ -1331,14 +1303,6 @@ static const struct command_registration jtag_command_handlers[] = { .help = "print current scan chain configuration", .usage = "" }, - { - .name = "jtag_reset", - .handler = handle_jtag_reset_command, - .mode = COMMAND_EXEC, - .help = "Set reset line values. Value '1' is active, " - "value '0' is inactive.", - .usage = "trst_active srst_active", - }, { .name = "runtest", .handler = handle_runtest_command, From 5d08bcb715599466dc88d1cdf5b599a7bba1be6a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 14 Aug 2019 14:53:24 +0200 Subject: [PATCH 061/354] tcl: update scripts after "jtag_reset" got deprecated Avoid annoying "deprecated" messages in the scripts distributed with OpenOCD code. Change-Id: I82d27cd420db30f0653efbd286a627ef56a8c1fd Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5287 Tested-by: jenkins Reviewed-by: Tomas Vanek --- tcl/board/openrd.cfg | 4 ++-- tcl/board/renesas_gen2_common.cfg | 4 ++-- tcl/board/renesas_salvator-xs.cfg | 4 ++-- tcl/board/sheevaplug.cfg | 4 ++-- tcl/target/pxa255.cfg | 6 +++--- tcl/test/syntax1.cfg | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tcl/board/openrd.cfg b/tcl/board/openrd.cfg index db3cb0326..7659b0749 100644 --- a/tcl/board/openrd.cfg +++ b/tcl/board/openrd.cfg @@ -25,10 +25,10 @@ proc openrd_init { } { # possible that initial tap examination failed. So let's # re-examine the target again here when nSRST is asserted which # should then succeed. - jtag_reset 0 1 + adapter assert srst feroceon.cpu arp_examine halt 0 - jtag_reset 0 0 + adapter deassert srst wait_halt arm mcr 15 0 0 1 0 0x00052078 diff --git a/tcl/board/renesas_gen2_common.cfg b/tcl/board/renesas_gen2_common.cfg index 00fa777c5..3e4579b91 100644 --- a/tcl/board/renesas_gen2_common.cfg +++ b/tcl/board/renesas_gen2_common.cfg @@ -4,10 +4,10 @@ reset_config trst_and_srst srst_nogate proc init_reset {mode} { # Assert both resets: equivalent to a power-on reset - jtag_reset 1 1 + adapter assert trst assert srst # Deassert TRST to begin TAP communication - jtag_reset 0 1 + adapter deassert trst assert srst # TAP should now be responsive, validate the scan-chain jtag arp_init diff --git a/tcl/board/renesas_salvator-xs.cfg b/tcl/board/renesas_salvator-xs.cfg index 1558a5274..e6f4da337 100644 --- a/tcl/board/renesas_salvator-xs.cfg +++ b/tcl/board/renesas_salvator-xs.cfg @@ -12,10 +12,10 @@ reset_config trst_and_srst srst_nogate proc init_reset {mode} { # Assert both resets: equivalent to a power-on reset - jtag_reset 1 1 + adapter assert trst assert srst # Deassert TRST to begin TAP communication - jtag_reset 0 1 + adapter deassert trst assert srst # TAP should now be responsive, validate the scan-chain jtag arp_init diff --git a/tcl/board/sheevaplug.cfg b/tcl/board/sheevaplug.cfg index ff333ca77..0d21be37c 100644 --- a/tcl/board/sheevaplug.cfg +++ b/tcl/board/sheevaplug.cfg @@ -25,10 +25,10 @@ proc sheevaplug_init { } { # possible that initial tap examination failed. So let's # re-examine the target again here when nSRST is asserted which # should then succeed. - jtag_reset 0 1 + adapter assert srst feroceon.cpu arp_examine halt 0 - jtag_reset 0 0 + adapter deassert srst wait_halt arm mcr 15 0 0 1 0 0x00052078 diff --git a/tcl/target/pxa255.cfg b/tcl/target/pxa255.cfg index 386242597..4b222de08 100644 --- a/tcl/target/pxa255.cfg +++ b/tcl/target/pxa255.cfg @@ -38,11 +38,11 @@ reset_config trst_and_srst separate srst_nogate # reset processing that works with PXA proc init_reset {mode} { # assert both resets; equivalent to power-on reset - jtag_reset 1 1 + adapter assert trst assert srst # drop TRST after at least 32 cycles sleep 1 - jtag_reset 0 1 + adapter deassert trst assert srst # minimum 32 TCK cycles to wake up the controller runtest 50 @@ -51,7 +51,7 @@ proc init_reset {mode} { jtag arp_init # ... and take it out of reset - jtag_reset 0 0 + adapter deassert trst deassert srst } proc jtag_init {} { diff --git a/tcl/test/syntax1.cfg b/tcl/test/syntax1.cfg index 79d538480..5d013f073 100644 --- a/tcl/test/syntax1.cfg +++ b/tcl/test/syntax1.cfg @@ -5,8 +5,8 @@ jtag_ntrst_delay 200 reset_config trst_and_srst srst_pulls_trst #LPCs need reset pulled while RTCK is low. 0 to activate JTAG, power-on reset is not enough -jtag_reset 1 1 -jtag_reset 0 0 +adapter assert trst assert srst +adapter deassert trst deassert srst #jtag scan chain #format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE) From be2d25efcc0132e02c76c304487a8759ca587b0c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 23 Jan 2019 16:46:31 +0100 Subject: [PATCH 062/354] arm_adi_v5: add API send_sequence() and use it The method to send an arbitrary sequence to DAP depends on the transport and is thus different on JTAG and SWD. This is already coded in dap_to_jtag() and dap_to_swd(). Add a new API send_sequence() in struct dap_ops. Add the implementations of send_sequence() in adi_v5_jtag.c and adi_v5_swd.c Rewrite dap_to_jtag() and dap_to_swd() using the new API. Move the enum swd_special_seq in arm_adi_v5.h to solve a circular dependencies among swd.h and arm_adi_v5.h Change-Id: I9db13a00f129761eab283783c094cfff2dd92610 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4902 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/swd.h | 8 -------- src/target/adi_v5_jtag.c | 24 ++++++++++++++++++++++++ src/target/adi_v5_swd.c | 9 +++++++++ src/target/arm_adi_v5.c | 38 ++------------------------------------ src/target/arm_adi_v5.h | 28 ++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 44 deletions(-) diff --git a/src/jtag/swd.h b/src/jtag/swd.h index 0b32105a2..0d1702c73 100644 --- a/src/jtag/swd.h +++ b/src/jtag/swd.h @@ -213,14 +213,6 @@ static const uint8_t swd_seq_dormant_to_jtag[] = { }; static const unsigned swd_seq_dormant_to_jtag_len = 160; -enum swd_special_seq { - LINE_RESET, - JTAG_TO_SWD, - SWD_TO_JTAG, - SWD_TO_DORMANT, - DORMANT_TO_SWD, -}; - struct swd_driver { /** * Initialize the debug link so it can perform SWD operations. diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c index df8113492..c2100eb47 100644 --- a/src/target/adi_v5_jtag.c +++ b/src/target/adi_v5_jtag.c @@ -38,6 +38,7 @@ #include "arm_adi_v5.h" #include #include +#include /*#define DEBUG_WAIT*/ @@ -663,6 +664,28 @@ static int jtag_check_reconnect(struct adiv5_dap *dap) return ERROR_OK; } +static int jtag_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq) +{ + int retval; + + switch (seq) { + case JTAG_TO_SWD: + retval = jtag_add_tms_seq(swd_seq_jtag_to_swd_len, + swd_seq_jtag_to_swd, TAP_INVALID); + break; + case SWD_TO_JTAG: + retval = jtag_add_tms_seq(swd_seq_swd_to_jtag_len, + swd_seq_swd_to_jtag, TAP_RESET); + break; + default: + LOG_ERROR("Sequence %d not supported", seq); + return ERROR_FAIL; + } + if (retval == ERROR_OK) + retval = jtag_execute_queue(); + return retval; +} + static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data) { @@ -782,6 +805,7 @@ static int jtag_dp_sync(struct adiv5_dap *dap) */ const struct dap_ops jtag_dp_ops = { .connect = jtag_connect, + .send_sequence = jtag_send_sequence, .queue_dp_read = jtag_dp_q_read, .queue_dp_write = jtag_dp_q_write, .queue_ap_read = jtag_ap_q_read, diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index 594b5081f..a3735661b 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -142,6 +142,14 @@ static int swd_connect(struct adiv5_dap *dap) return status; } +static int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq) +{ + const struct swd_driver *swd = adiv5_dap_swd_driver(dap); + assert(swd); + + return swd->switch_seq(seq); +} + static inline int check_sync(struct adiv5_dap *dap) { return do_sync ? swd_run_inner(dap) : ERROR_OK; @@ -320,6 +328,7 @@ static void swd_quit(struct adiv5_dap *dap) const struct dap_ops swd_dap_ops = { .connect = swd_connect, + .send_sequence = swd_send_sequence, .queue_dp_read = swd_queue_dp_read, .queue_dp_write = swd_queue_dp_write, .queue_ap_read = swd_queue_ap_read, diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index d2ec960a8..2d47da3ea 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -804,26 +804,9 @@ int mem_ap_init(struct adiv5_ap *ap) */ int dap_to_swd(struct adiv5_dap *dap) { - int retval; - LOG_DEBUG("Enter SWD mode"); - if (transport_is_jtag()) { - retval = jtag_add_tms_seq(swd_seq_jtag_to_swd_len, - swd_seq_jtag_to_swd, TAP_INVALID); - if (retval == ERROR_OK) - retval = jtag_execute_queue(); - return retval; - } - - if (transport_is_swd()) { - const struct swd_driver *swd = adiv5_dap_swd_driver(dap); - - return swd->switch_seq(JTAG_TO_SWD); - } - - LOG_ERROR("Nor JTAG nor SWD transport"); - return ERROR_FAIL; + return dap_send_sequence(dap, JTAG_TO_SWD); } /** @@ -839,26 +822,9 @@ int dap_to_swd(struct adiv5_dap *dap) */ int dap_to_jtag(struct adiv5_dap *dap) { - int retval; - LOG_DEBUG("Enter JTAG mode"); - if (transport_is_jtag()) { - retval = jtag_add_tms_seq(swd_seq_swd_to_jtag_len, - swd_seq_swd_to_jtag, TAP_RESET); - if (retval == ERROR_OK) - retval = jtag_execute_queue(); - return retval; - } - - if (transport_is_swd()) { - const struct swd_driver *swd = adiv5_dap_swd_driver(dap); - - return swd->switch_seq(SWD_TO_JTAG); - } - - LOG_ERROR("Nor JTAG nor SWD transport"); - return ERROR_FAIL; + return dap_send_sequence(dap, SWD_TO_JTAG); } /* CID interpretation -- see ARM IHI 0029B section 3 diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index ee04d4177..88b7e5c87 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -158,6 +158,15 @@ #define DP_APSEL_MAX (255) #define DP_APSEL_INVALID (-1) +/* FIXME: not SWD specific; should be renamed, e.g. adiv5_special_seq */ +enum swd_special_seq { + LINE_RESET, + JTAG_TO_SWD, + SWD_TO_JTAG, + SWD_TO_DORMANT, + DORMANT_TO_SWD, +}; + /** * This represents an ARM Debug Interface (v5) Access Port (AP). * Most common is a MEM-AP, for memory access. @@ -291,6 +300,10 @@ struct adiv5_dap { struct dap_ops { /** connect operation for SWD */ int (*connect)(struct adiv5_dap *dap); + + /** send a sequence to the DAP */ + int (*send_sequence)(struct adiv5_dap *dap, enum swd_special_seq seq); + /** DP register read. */ int (*queue_dp_read)(struct adiv5_dap *dap, unsigned reg, uint32_t *data); @@ -338,6 +351,21 @@ enum ap_type { AP_TYPE_AHB5_AP = 0x5, /* AHB5 Memory-AP. */ }; +/** + * Send an adi-v5 sequence to the DAP. + * + * @param dap The DAP used for reading. + * @param seq The sequence to send. + * + * @return ERROR_OK for success, else a fault code. + */ +static inline int dap_send_sequence(struct adiv5_dap *dap, + enum swd_special_seq seq) +{ + assert(dap->ops != NULL); + return dap->ops->send_sequence(dap, seq); +} + /** * Queue a DP register read. * Note that not all DP registers are readable; also, that JTAG and SWD From 9f1529da4fcc7d1e508ab9ea4dc915800d68e730 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 3 Dec 2019 08:17:56 +0000 Subject: [PATCH 063/354] flash/nor/stm32f2x: Support value line chips with trimmed flash The current code assumes an STM32's flash bank is laid-out in either of two configurations: - 4 x 16kB + 1 x 64kB + n x 128kB - 4 x 32kB + 1 x 128kB + n x 256kB This is quite ad-hoc but works fine in practice, as long as there are at least 5 sectors (if n=0). Unfortunately, some newer STM32s are shipping with only 64 kB of flash (4 x 16kB sectors). This patch still assumes the same sector layout, but only keeps adding sectors to the bank if the bank's capacity has not been reached. This prevents openocd from crashing on some newer STM32s. Change-Id: If00e5d7a328d11b399babc0bb2111e3ad8a3217e Signed-off-by: Romain Goyet Signed-off-by: Keir Fraser Reviewed-on: http://openocd.zylin.com/4926 Tested-by: jenkins Reviewed-by: Andreas Bolsch Reviewed-by: Tomas Vanek --- src/flash/nor/stm32f2x.c | 75 ++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 19 deletions(-) diff --git a/src/flash/nor/stm32f2x.c b/src/flash/nor/stm32f2x.c index ea35fd05d..c1283bb3f 100644 --- a/src/flash/nor/stm32f2x.c +++ b/src/flash/nor/stm32f2x.c @@ -894,31 +894,68 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK); } -static int setup_sector(struct flash_bank *bank, int start, int num, int size) +static void setup_sector(struct flash_bank *bank, int i, int size) { + assert(i < bank->num_sectors); + bank->sectors[i].offset = bank->size; + bank->sectors[i].size = size; + bank->size += bank->sectors[i].size; + LOG_DEBUG("sector %d: %dkBytes", i, size >> 10); +} - for (int i = start; i < (start + num) ; i++) { - assert(i < bank->num_sectors); - bank->sectors[i].offset = bank->size; - bank->sectors[i].size = size; - bank->size += bank->sectors[i].size; - LOG_DEBUG("sector %d: %d kBytes", i, size >> 10); +static uint16_t sector_size_in_kb(int i, uint16_t max_sector_size_in_kb) +{ + assert(i >= 0); + if (i < 4) + return max_sector_size_in_kb / 8; + if (i == 4) + return max_sector_size_in_kb / 2; + return max_sector_size_in_kb; +} + +static int calculate_number_of_sectors(struct flash_bank *bank, + uint16_t flash_size_in_kb, + uint16_t max_sector_size_in_kb) +{ + struct stm32x_flash_bank *stm32x_info = bank->driver_priv; + uint16_t remaining_flash_size_in_kb = flash_size_in_kb; + int nr_sectors; + + /* Dual Bank Flash has two identically-arranged banks of sectors. */ + if (stm32x_info->has_large_mem) + remaining_flash_size_in_kb /= 2; + + for (nr_sectors = 0; remaining_flash_size_in_kb > 0; nr_sectors++) { + uint16_t size_in_kb = sector_size_in_kb(nr_sectors, max_sector_size_in_kb); + if (size_in_kb > remaining_flash_size_in_kb) { + LOG_INFO("%s Bank %" PRIu16 " kiB final sector clipped to %" PRIu16 " kiB", + stm32x_info->has_large_mem ? "Dual" : "Single", + flash_size_in_kb, remaining_flash_size_in_kb); + remaining_flash_size_in_kb = 0; + } else { + remaining_flash_size_in_kb -= size_in_kb; + } } - return start + num; + return stm32x_info->has_large_mem ? nr_sectors*2 : nr_sectors; } static void setup_bank(struct flash_bank *bank, int start, uint16_t flash_size_in_kb, uint16_t max_sector_size_in_kb) { - int remain; - - start = setup_sector(bank, start, 4, (max_sector_size_in_kb / 8) * 1024); - start = setup_sector(bank, start, 1, (max_sector_size_in_kb / 2) * 1024); - - /* remaining sectors all of size max_sector_size_in_kb */ - remain = (flash_size_in_kb / max_sector_size_in_kb) - 1; - start = setup_sector(bank, start, remain, max_sector_size_in_kb * 1024); + uint16_t remaining_flash_size_in_kb = flash_size_in_kb; + int sector_index = 0; + while (remaining_flash_size_in_kb > 0) { + uint16_t size_in_kb = sector_size_in_kb(sector_index, max_sector_size_in_kb); + if (size_in_kb > remaining_flash_size_in_kb) { + /* Clip last sector. Already warned in + * calculate_number_of_sectors. */ + size_in_kb = remaining_flash_size_in_kb; + } + setup_sector(bank, start + sector_index, size_in_kb * 1024); + remaining_flash_size_in_kb -= size_in_kb; + sector_index++; + } } static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id) @@ -1150,12 +1187,12 @@ static int stm32x_probe(struct flash_bank *bank) } /* calculate numbers of pages */ - int num_pages = flash_size_in_kb / max_sector_size_in_kb - + (stm32x_info->has_large_mem ? 8 : 4); + int num_pages = calculate_number_of_sectors( + bank, flash_size_in_kb, max_sector_size_in_kb); bank->base = base_address; bank->num_sectors = num_pages; - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); + bank->sectors = calloc(num_pages, sizeof(struct flash_sector)); for (i = 0; i < num_pages; i++) { bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 0; From 790bd27181c13f816fcce59f3ab23d3b2f21f94d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 19 Apr 2019 20:34:36 +0200 Subject: [PATCH 064/354] flash/nor: Factor out cfi_spansion_unlock_seq() Factor out the spansion unlock sequence to deduplicate the code. Change-Id: Id78522e9a2f0e701870ef816772289d08257476a Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5144 Tested-by: jenkins Reviewed-by: Paul Fertser --- src/flash/nor/cfi.c | 48 +++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 04fa83b55..34f200b4a 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -898,6 +898,23 @@ static int cfi_intel_erase(struct flash_bank *bank, int first, int last) return cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); } +static int cfi_spansion_unlock_seq(struct flash_bank *bank) +{ + int retval; + struct cfi_flash_bank *cfi_info = bank->driver_priv; + struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; + + retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); + if (retval != ERROR_OK) + return retval; + + retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); + if (retval != ERROR_OK) + return retval; + + return ERROR_OK; +} + static int cfi_spansion_erase(struct flash_bank *bank, int first, int last) { int retval; @@ -906,11 +923,7 @@ static int cfi_spansion_erase(struct flash_bank *bank, int first, int last) int i; for (i = first; i <= last; i++) { - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); + retval = cfi_spansion_unlock_seq(bank); if (retval != ERROR_OK) return retval; @@ -918,11 +931,7 @@ static int cfi_spansion_erase(struct flash_bank *bank, int first, int last) if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); + retval = cfi_spansion_unlock_seq(bank); if (retval != ERROR_OK) return retval; @@ -2102,11 +2111,7 @@ static int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint3 struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; struct target *target = bank->target; - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); + retval = cfi_spansion_unlock_seq(bank); if (retval != ERROR_OK) return retval; @@ -2137,7 +2142,6 @@ static int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct target *target = bank->target; - struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; /* Calculate buffer size and boundary mask * buffersize is (buffer size per chip) * (number of chips) @@ -2163,11 +2167,7 @@ static int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word } /* Unlock */ - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); + retval = cfi_spansion_unlock_seq(bank); if (retval != ERROR_OK) return retval; @@ -2958,11 +2958,7 @@ static int cfi_spansion_protect_check(struct flash_bank *bank) struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; int i; - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); - if (retval != ERROR_OK) - return retval; - - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); + retval = cfi_spansion_unlock_seq(bank); if (retval != ERROR_OK) return retval; From db23c13d42f49da238bed548d3421c1651ad7072 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 21 Apr 2019 15:54:38 +0200 Subject: [PATCH 065/354] flash/nor: Factor out CFI memory read/write functions Create separate memory read/write functions which facilitate access to the CFI NOR, so that they can be replaced by controller-specific functions if necessary. This would become necessary when implementing support for e.g. HyperFlash controllers, which do not directly map the HyperFlash into the address space. Change-Id: I1bba1edfd397cb37bfedb43efe2dd03feb26a375 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5145 Tested-by: jenkins Reviewed-by: Paul Fertser --- src/flash/nor/cfi.c | 50 +++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 34f200b4a..c22bcdecb 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -131,6 +131,20 @@ static inline uint32_t flash_address(struct flash_bank *bank, int sector, uint32 } } +static int cfi_target_write_memory(struct target *target, target_addr_t addr, + uint32_t size, uint32_t count, + const uint8_t *buffer) +{ + return target_write_memory(target, addr, size, count, buffer); +} + +static int cfi_target_read_memory(struct target *target, target_addr_t addr, + uint32_t size, uint32_t count, + uint8_t *buffer) +{ + return target_read_memory(target, addr, size, count, buffer); +} + static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf) { int i; @@ -156,7 +170,7 @@ static int cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t addre uint8_t command[CFI_MAX_BUS_WIDTH]; cfi_command(bank, cmd, command); - return target_write_memory(bank->target, address, bank->bus_width, 1, command); + return cfi_target_write_memory(bank->target, address, bank->bus_width, 1, command); } /* read unsigned 8-bit value from the bank @@ -170,7 +184,7 @@ static int cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset, ui uint8_t data[CFI_MAX_BUS_WIDTH]; int retval; - retval = target_read_memory(target, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 1, data); if (retval != ERROR_OK) return retval; @@ -195,7 +209,7 @@ static int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint int i; int retval; - retval = target_read_memory(target, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 1, data); if (retval != ERROR_OK) return retval; @@ -225,13 +239,13 @@ static int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, u if (cfi_info->x16_as_x8) { uint8_t i; for (i = 0; i < 2; i++) { - retval = target_read_memory(target, flash_address(bank, sector, offset + i), + retval = cfi_target_read_memory(target, flash_address(bank, sector, offset + i), bank->bus_width, 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) return retval; } } else { - retval = target_read_memory(target, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 2, data); if (retval != ERROR_OK) return retval; @@ -255,13 +269,13 @@ static int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, u if (cfi_info->x16_as_x8) { uint8_t i; for (i = 0; i < 4; i++) { - retval = target_read_memory(target, flash_address(bank, sector, offset + i), + retval = cfi_target_read_memory(target, flash_address(bank, sector, offset + i), bank->bus_width, 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) return retval; } } else { - retval = target_read_memory(target, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(target, flash_address(bank, sector, offset), bank->bus_width, 4, data); if (retval != ERROR_OK) return retval; @@ -1997,7 +2011,7 @@ static int cfi_intel_write_word(struct flash_bank *bank, uint8_t *word, uint32_t if (retval != ERROR_OK) return retval; - retval = target_write_memory(target, address, bank->bus_width, 1, word); + retval = cfi_target_write_memory(target, address, bank->bus_width, 1, word); if (retval != ERROR_OK) return retval; @@ -2078,7 +2092,7 @@ static int cfi_intel_write_words(struct flash_bank *bank, const uint8_t *word, if (retval != ERROR_OK) return retval; - retval = target_write_memory(target, address, bank->bus_width, bufferwsize, word); + retval = cfi_target_write_memory(target, address, bank->bus_width, bufferwsize, word); if (retval != ERROR_OK) return retval; @@ -2119,7 +2133,7 @@ static int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint3 if (retval != ERROR_OK) return retval; - retval = target_write_memory(target, address, bank->bus_width, 1, word); + retval = cfi_target_write_memory(target, address, bank->bus_width, 1, word); if (retval != ERROR_OK) return retval; @@ -2181,7 +2195,7 @@ static int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word if (retval != ERROR_OK) return retval; - retval = target_write_memory(target, address, bank->bus_width, bufferwsize, word); + retval = cfi_target_write_memory(target, address, bank->bus_width, bufferwsize, word); if (retval != ERROR_OK) return retval; @@ -2283,7 +2297,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u LOG_INFO("Fixup %d unaligned read head bytes", align); /* read a complete word from flash */ - retval = target_read_memory(target, read_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(target, read_p, bank->bus_width, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2296,7 +2310,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u align = count / bank->bus_width; if (align) { - retval = target_read_memory(target, read_p, bank->bus_width, align, buffer); + retval = cfi_target_read_memory(target, read_p, bank->bus_width, align, buffer); if (retval != ERROR_OK) return retval; @@ -2309,7 +2323,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u LOG_INFO("Fixup %" PRIu32 " unaligned read tail bytes", count); /* read a complete word from flash */ - retval = target_read_memory(target, read_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(target, read_p, bank->bus_width, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2354,7 +2368,7 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of LOG_INFO("Fixup %d unaligned head bytes", align); /* read a complete word from flash */ - retval = target_read_memory(target, write_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(target, write_p, bank->bus_width, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2474,7 +2488,7 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of LOG_INFO("Fixup %" PRId32 " unaligned tail bytes", count); /* read a complete word from flash */ - retval = target_read_memory(target, write_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(target, write_p, bank->bus_width, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2624,11 +2638,11 @@ static int cfi_probe(struct flash_bank *bank) if (retval != ERROR_OK) return retval; - retval = target_read_memory(target, flash_address(bank, 0, 0x00), + retval = cfi_target_read_memory(target, flash_address(bank, 0, 0x00), bank->bus_width, 1, value_buf0); if (retval != ERROR_OK) return retval; - retval = target_read_memory(target, flash_address(bank, 0, 0x01), + retval = cfi_target_read_memory(target, flash_address(bank, 0, 0x01), bank->bus_width, 1, value_buf1); if (retval != ERROR_OK) return retval; From 8850eb8f2c5142346e5a450b13d56130691cd894 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 31 Aug 2019 11:08:16 +0200 Subject: [PATCH 066/354] swd: get rid of jtag queue to assert/deassert srst The transport SWD uses the JTAG queue to assert/deassert the system reset srst. This is the major inconsistency that has to be removed to properly split JTAG and SWD. Introduce a new driver API, reset(), to controls both the signals trst and srst in the driver, skipping the JTAG queue. Put the new API in struct jtag_interface, even if in this patch it's used for SWD only; the goal is to get it reused by the other transports. Add the implementation of the API in all the drivers that implement SWD. Such implementation is almost the same of the old code in JTAG queue. Create a wrapper adapter_system_reset() to use the new API and remove the SWD specific swd_add_reset(). In the wrapper replace jtag_add_sleep() with jtag_sleep(), because the former uses the JTAG queue too. Rename the old jtag_add_reset() as legacy_jtag_add_reset() with the target to remove it when all drivers would be ported to the new reset API. Create a new jtag_add_reset() that calls the legacy function for drivers still on the old reset API. Use the new API also on JTAG transport for the drivers that can support both SWD and JTAG. For the moment, do not modify the implementation of JTAG-only drivers, which will continue using the usual method. This should be cleaned-up in future commits. Change-Id: I32331c88313f6059b25e12c6bb0156aebc1c074f Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4895 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/core.c | 169 +++++++++++++++++++++++++------ src/jtag/drivers/bcm2835gpio.c | 3 +- src/jtag/drivers/buspirate.c | 21 ++-- src/jtag/drivers/cmsis_dap_usb.c | 12 +-- src/jtag/drivers/ftdi.c | 49 ++++----- src/jtag/drivers/imx_gpio.c | 3 +- src/jtag/drivers/jlink.c | 22 ++-- src/jtag/drivers/kitprog.c | 16 +-- src/jtag/drivers/sysfsgpio.c | 2 +- src/jtag/drivers/vsllink.c | 21 +--- src/jtag/drivers/xds110.c | 42 ++++---- src/jtag/interface.h | 14 +++ src/jtag/swd.h | 1 - src/target/adi_v5_swd.c | 2 +- 14 files changed, 233 insertions(+), 144 deletions(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index 871b4d2bd..97caeb18a 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -613,53 +613,42 @@ void jtag_add_clocks(int num_cycles) } } -void swd_add_reset(int req_srst) +static int adapter_system_reset(int req_srst) { + int retval; + if (req_srst) { if (!(jtag_reset_config & RESET_HAS_SRST)) { LOG_ERROR("BUG: can't assert SRST"); - jtag_set_error(ERROR_FAIL); - return; + return ERROR_FAIL; } req_srst = 1; } /* Maybe change SRST signal state */ if (jtag_srst != req_srst) { - int retval; - - retval = interface_jtag_add_reset(0, req_srst); - if (retval != ERROR_OK) - jtag_set_error(retval); - else - retval = jtag_execute_queue(); - + retval = jtag->reset(0, req_srst); if (retval != ERROR_OK) { - LOG_ERROR("TRST/SRST error"); - return; + LOG_ERROR("SRST error"); + return ERROR_FAIL; } - - /* SRST resets everything hooked up to that signal */ jtag_srst = req_srst; - if (jtag_srst) { + + if (req_srst) { LOG_DEBUG("SRST line asserted"); if (adapter_nsrst_assert_width) - jtag_add_sleep(adapter_nsrst_assert_width * 1000); + jtag_sleep(adapter_nsrst_assert_width * 1000); } else { LOG_DEBUG("SRST line released"); if (adapter_nsrst_delay) - jtag_add_sleep(adapter_nsrst_delay * 1000); - } - - retval = jtag_execute_queue(); - if (retval != ERROR_OK) { - LOG_ERROR("SRST timings error"); - return; + jtag_sleep(adapter_nsrst_delay * 1000); } } + + return ERROR_OK; } -void jtag_add_reset(int req_tlr_or_trst, int req_srst) +static void legacy_jtag_add_reset(int req_tlr_or_trst, int req_srst) { int trst_with_tlr = 0; int new_srst = 0; @@ -767,6 +756,118 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) } } +/* FIXME: name is misleading; we do not plan to "add" reset into jtag queue */ +void jtag_add_reset(int req_tlr_or_trst, int req_srst) +{ + int retval; + int trst_with_tlr = 0; + int new_srst = 0; + int new_trst = 0; + + if (!jtag->reset) { + legacy_jtag_add_reset(req_tlr_or_trst, req_srst); + return; + } + + /* Without SRST, we must use target-specific JTAG operations + * on each target; callers should not be requesting SRST when + * that signal doesn't exist. + * + * RESET_SRST_PULLS_TRST is a board or chip level quirk, which + * can kick in even if the JTAG adapter can't drive TRST. + */ + if (req_srst) { + if (!(jtag_reset_config & RESET_HAS_SRST)) { + LOG_ERROR("BUG: can't assert SRST"); + jtag_set_error(ERROR_FAIL); + return; + } + if ((jtag_reset_config & RESET_SRST_PULLS_TRST) != 0 + && !req_tlr_or_trst) { + LOG_ERROR("BUG: can't assert only SRST"); + jtag_set_error(ERROR_FAIL); + return; + } + new_srst = 1; + } + + /* JTAG reset (entry to TAP_RESET state) can always be achieved + * using TCK and TMS; that may go through a TAP_{IR,DR}UPDATE + * state first. TRST accelerates it, and bypasses those states. + * + * RESET_TRST_PULLS_SRST is a board or chip level quirk, which + * can kick in even if the JTAG adapter can't drive SRST. + */ + if (req_tlr_or_trst) { + if (!(jtag_reset_config & RESET_HAS_TRST)) + trst_with_tlr = 1; + else if ((jtag_reset_config & RESET_TRST_PULLS_SRST) != 0 + && !req_srst) + trst_with_tlr = 1; + else + new_trst = 1; + } + + /* Maybe change TRST and/or SRST signal state */ + if (jtag_srst != new_srst || jtag_trst != new_trst) { + /* guarantee jtag queue empty before changing reset status */ + jtag_execute_queue(); + + retval = jtag->reset(new_trst, new_srst); + if (retval != ERROR_OK) { + jtag_set_error(retval); + LOG_ERROR("TRST/SRST error"); + return; + } + } + + /* SRST resets everything hooked up to that signal */ + if (jtag_srst != new_srst) { + jtag_srst = new_srst; + if (jtag_srst) { + LOG_DEBUG("SRST line asserted"); + if (adapter_nsrst_assert_width) + jtag_add_sleep(adapter_nsrst_assert_width * 1000); + } else { + LOG_DEBUG("SRST line released"); + if (adapter_nsrst_delay) + jtag_add_sleep(adapter_nsrst_delay * 1000); + } + } + + /* Maybe enter the JTAG TAP_RESET state ... + * - using only TMS, TCK, and the JTAG state machine + * - or else more directly, using TRST + * + * TAP_RESET should be invisible to non-debug parts of the system. + */ + if (trst_with_tlr) { + LOG_DEBUG("JTAG reset with TLR instead of TRST"); + jtag_add_tlr(); + + } else if (jtag_trst != new_trst) { + jtag_trst = new_trst; + if (jtag_trst) { + LOG_DEBUG("TRST line asserted"); + tap_set_state(TAP_RESET); + if (jtag_ntrst_assert_width) + jtag_add_sleep(jtag_ntrst_assert_width * 1000); + } else { + LOG_DEBUG("TRST line released"); + if (jtag_ntrst_delay) + jtag_add_sleep(jtag_ntrst_delay * 1000); + + /* We just asserted nTRST, so we're now in TAP_RESET. + * Inform possible listeners about this, now that + * JTAG instructions and data can be shifted. This + * sequence must match jtag_add_tlr(). + */ + jtag_call_event_callbacks(JTAG_TRST_ASSERTED); + jtag_notify_event(JTAG_TRST_ASSERTED); + } + } +} + void jtag_add_sleep(uint32_t us) { /** @todo Here, keep_alive() appears to be a layering violation!!! */ @@ -1557,17 +1658,19 @@ int adapter_quit(void) int swd_init_reset(struct command_context *cmd_ctx) { - int retval = adapter_init(cmd_ctx); + int retval, retval1; + + retval = adapter_init(cmd_ctx); if (retval != ERROR_OK) return retval; LOG_DEBUG("Initializing with hard SRST reset"); if (jtag_reset_config & RESET_HAS_SRST) - swd_add_reset(1); - swd_add_reset(0); - retval = jtag_execute_queue(); - return retval; + retval = adapter_system_reset(1); + retval1 = adapter_system_reset(0); + + return (retval == ERROR_OK) ? retval1 : retval; } int jtag_init_reset(struct command_context *cmd_ctx) @@ -1916,7 +2019,7 @@ int adapter_resets(int trst, int srst) LOG_ERROR("adapter has no srst signal"); return ERROR_FAIL; } - swd_add_reset(srst); + adapter_system_reset(srst); return ERROR_OK; } else if (transport_is_hla()) { if (trst == TRST_ASSERT) { @@ -1949,7 +2052,7 @@ void adapter_assert_reset(void) else jtag_add_reset(0, 1); } else if (transport_is_swd()) - swd_add_reset(1); + adapter_system_reset(1); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", get_current_transport()->name); @@ -1962,7 +2065,7 @@ void adapter_deassert_reset(void) if (transport_is_jtag()) jtag_add_reset(0, 0); else if (transport_is_swd()) - swd_add_reset(0); + adapter_system_reset(0); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", get_current_transport()->name); diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c index 36e10b6da..60316f17d 100644 --- a/src/jtag/drivers/bcm2835gpio.c +++ b/src/jtag/drivers/bcm2835gpio.c @@ -51,7 +51,6 @@ static volatile uint32_t *pio_base; static bb_value_t bcm2835gpio_read(void); static int bcm2835gpio_write(int tck, int tms, int tdi); -static int bcm2835gpio_reset(int trst, int srst); static int bcm2835_swdio_read(void); static void bcm2835_swdio_drive(bool is_output); @@ -62,7 +61,6 @@ static int bcm2835gpio_quit(void); static struct bitbang_interface bcm2835gpio_bitbang = { .read = bcm2835gpio_read, .write = bcm2835gpio_write, - .reset = bcm2835gpio_reset, .swdio_read = bcm2835_swdio_read, .swdio_drive = bcm2835_swdio_drive, .blink = NULL @@ -419,6 +417,7 @@ struct jtag_interface bcm2835gpio_interface = { .commands = bcm2835gpio_command_handlers, .init = bcm2835gpio_init, .quit = bcm2835gpio_quit, + .reset = bcm2835gpio_reset, }; static bool bcm2835gpio_jtag_mode_possible(void) diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c index 872896ba3..23d1547a9 100644 --- a/src/jtag/drivers/buspirate.c +++ b/src/jtag/drivers/buspirate.c @@ -34,6 +34,7 @@ static int buspirate_execute_queue(void); static int buspirate_init(void); static int buspirate_quit(void); +static int buspirate_reset(int trst, int srst); static void buspirate_end_state(tap_state_t state); static void buspirate_state_move(void); @@ -133,7 +134,6 @@ static void buspirate_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command); static void buspirate_tap_make_space(int scan, int bits); -static void buspirate_reset(int trst, int srst); static void buspirate_set_feature(int, char, char); static void buspirate_set_mode(int, char); static void buspirate_set_speed(int, char); @@ -213,18 +213,6 @@ static int buspirate_execute_queue(void) buffer, scan_size, cmd->cmd.scan); break; - case JTAG_RESET: - LOG_DEBUG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, cmd->cmd.reset->srst); - - /* flush buffers, so we can reset */ - buspirate_tap_execute(); - - if (cmd->cmd.reset->trst == 1) - tap_set_state(TAP_RESET); - buspirate_reset(cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - break; case JTAG_SLEEP: LOG_DEBUG_IO("sleep %i", cmd->cmd.sleep->us); buspirate_tap_execute(); @@ -555,7 +543,8 @@ struct jtag_interface buspirate_interface = { .transports = buspirate_transports, .swd = &buspirate_swd, .init = buspirate_init, - .quit = buspirate_quit + .quit = buspirate_quit, + .reset = buspirate_reset, }; /*************** jtag execute commands **********************/ @@ -860,7 +849,7 @@ static void buspirate_tap_append_scan(int length, uint8_t *buffer, /*************** wrapper functions *********************/ /* (1) assert or (0) deassert reset lines */ -static void buspirate_reset(int trst, int srst) +static int buspirate_reset(int trst, int srst) { LOG_DEBUG("trst: %i, srst: %i", trst, srst); @@ -873,6 +862,8 @@ static void buspirate_reset(int trst, int srst) buspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_DISABLE); else buspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_ENABLE); + + return ERROR_OK; } static void buspirate_set_feature(int fd, char feat, char action) diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c index d52d698a4..c54b70c7d 100644 --- a/src/jtag/drivers/cmsis_dap_usb.c +++ b/src/jtag/drivers/cmsis_dap_usb.c @@ -1126,21 +1126,22 @@ static int cmsis_dap_quit(void) return ERROR_OK; } -static void cmsis_dap_execute_reset(struct jtag_command *cmd) +static int cmsis_dap_reset(int trst, int srst) { /* Set both TRST and SRST even if they're not enabled as * there's no way to tristate them */ output_pins = 0; - if (!cmd->cmd.reset->srst) + if (!srst) output_pins |= SWJ_PIN_SRST; - if (!cmd->cmd.reset->trst) + if (!trst) output_pins |= SWJ_PIN_TRST; int retval = cmsis_dap_cmd_DAP_SWJ_Pins(output_pins, SWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL); if (retval != ERROR_OK) LOG_ERROR("CMSIS-DAP: Interface reset failed"); + return retval; } static void cmsis_dap_execute_sleep(struct jtag_command *cmd) @@ -1581,10 +1582,6 @@ static void cmsis_dap_execute_tms(struct jtag_command *cmd) static void cmsis_dap_execute_command(struct jtag_command *cmd) { switch (cmd->type) { - case JTAG_RESET: - cmsis_dap_flush(); - cmsis_dap_execute_reset(cmd); - break; case JTAG_SLEEP: cmsis_dap_flush(); cmsis_dap_execute_sleep(cmd); @@ -1802,4 +1799,5 @@ struct jtag_interface cmsis_dap_interface = { .khz = cmsis_dap_khz, .init = cmsis_dap_init, .quit = cmsis_dap_quit, + .reset = cmsis_dap_reset, }; diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 5cd44a9d1..e645e9fae 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -517,46 +517,41 @@ static void ftdi_execute_scan(struct jtag_command *cmd) tap_state_name(tap_get_end_state())); } -static void ftdi_execute_reset(struct jtag_command *cmd) +static int ftdi_reset(int trst, int srst) { - LOG_DEBUG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, cmd->cmd.reset->srst); + struct signal *sig_ntrst = find_signal_by_name("nTRST"); + struct signal *sig_nsrst = find_signal_by_name("nSRST"); - if (cmd->cmd.reset->trst == 1 - || (cmd->cmd.reset->srst - && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) - tap_set_state(TAP_RESET); + LOG_DEBUG_IO("reset trst: %i srst %i", trst, srst); - struct signal *trst = find_signal_by_name("nTRST"); - if (cmd->cmd.reset->trst == 1) { - if (trst) - ftdi_set_signal(trst, '0'); + if (trst == 1) { + if (sig_ntrst) + ftdi_set_signal(sig_ntrst, '0'); else LOG_ERROR("Can't assert TRST: nTRST signal is not defined"); - } else if (trst && jtag_get_reset_config() & RESET_HAS_TRST && - cmd->cmd.reset->trst == 0) { + } else if (sig_ntrst && jtag_get_reset_config() & RESET_HAS_TRST && + trst == 0) { if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN) - ftdi_set_signal(trst, 'z'); + ftdi_set_signal(sig_ntrst, 'z'); else - ftdi_set_signal(trst, '1'); + ftdi_set_signal(sig_ntrst, '1'); } - struct signal *srst = find_signal_by_name("nSRST"); - if (cmd->cmd.reset->srst == 1) { - if (srst) - ftdi_set_signal(srst, '0'); + if (srst == 1) { + if (sig_nsrst) + ftdi_set_signal(sig_nsrst, '0'); else LOG_ERROR("Can't assert SRST: nSRST signal is not defined"); - } else if (srst && jtag_get_reset_config() & RESET_HAS_SRST && - cmd->cmd.reset->srst == 0) { + } else if (sig_nsrst && jtag_get_reset_config() & RESET_HAS_SRST && + srst == 0) { if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL) - ftdi_set_signal(srst, '1'); + ftdi_set_signal(sig_nsrst, '1'); else - ftdi_set_signal(srst, 'z'); + ftdi_set_signal(sig_nsrst, 'z'); } - LOG_DEBUG_IO("trst: %i, srst: %i", - cmd->cmd.reset->trst, cmd->cmd.reset->srst); + LOG_DEBUG_IO("trst: %i, srst: %i", trst, srst); + return ERROR_OK; } static void ftdi_execute_sleep(struct jtag_command *cmd) @@ -597,9 +592,6 @@ static void ftdi_execute_stableclocks(struct jtag_command *cmd) static void ftdi_execute_command(struct jtag_command *cmd) { switch (cmd->type) { - case JTAG_RESET: - ftdi_execute_reset(cmd); - break; case JTAG_RUNTEST: ftdi_execute_runtest(cmd); break; @@ -1248,6 +1240,7 @@ struct jtag_interface ftdi_interface = { .init = ftdi_initialize, .quit = ftdi_quit, + .reset = ftdi_reset, .speed = ftdi_speed, .speed_div = ftdi_speed_div, .khz = ftdi_khz, diff --git a/src/jtag/drivers/imx_gpio.c b/src/jtag/drivers/imx_gpio.c index 4923dab39..d677e8a7e 100644 --- a/src/jtag/drivers/imx_gpio.c +++ b/src/jtag/drivers/imx_gpio.c @@ -84,7 +84,6 @@ static inline bool gpio_level(int g) static bb_value_t imx_gpio_read(void); static int imx_gpio_write(int tck, int tms, int tdi); -static int imx_gpio_reset(int trst, int srst); static int imx_gpio_swdio_read(void); static void imx_gpio_swdio_drive(bool is_output); @@ -95,7 +94,6 @@ static int imx_gpio_quit(void); static struct bitbang_interface imx_gpio_bitbang = { .read = imx_gpio_read, .write = imx_gpio_write, - .reset = imx_gpio_reset, .swdio_read = imx_gpio_swdio_read, .swdio_drive = imx_gpio_swdio_drive, .blink = NULL @@ -441,6 +439,7 @@ struct jtag_interface imx_gpio_interface = { .commands = imx_gpio_command_handlers, .init = imx_gpio_init, .quit = imx_gpio_quit, + .reset = imx_gpio_reset, }; static bool imx_gpio_jtag_mode_possible(void) diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index d2a871225..402ff9917 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -94,6 +94,7 @@ static void jlink_path_move(int num_states, tap_state_t *path); static void jlink_stableclocks(int num_cycles); static void jlink_runtest(int num_cycles); static void jlink_reset(int trst, int srst); +static int jlink_reset_safe(int trst, int srst); static int jlink_swd_run_queue(void); static void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk); static int jlink_swd_switch_seq(enum swd_special_seq seq); @@ -251,16 +252,6 @@ static void jlink_execute_scan(struct jtag_command *cmd) tap_state_name(tap_get_end_state())); } -static void jlink_execute_reset(struct jtag_command *cmd) -{ - LOG_DEBUG_IO("reset trst: %i srst %i", cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - - jlink_flush(); - jlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst); - jlink_flush(); -} - static void jlink_execute_sleep(struct jtag_command *cmd) { LOG_DEBUG_IO("sleep %" PRIi32 "", cmd->cmd.sleep->us); @@ -286,9 +277,6 @@ static int jlink_execute_command(struct jtag_command *cmd) case JTAG_SCAN: jlink_execute_scan(cmd); break; - case JTAG_RESET: - jlink_execute_reset(cmd); - break; case JTAG_SLEEP: jlink_execute_sleep(cmd); break; @@ -956,6 +944,13 @@ static void jlink_reset(int trst, int srst) jaylink_jtag_set_trst(devh); } +static int jlink_reset_safe(int trst, int srst) +{ + jlink_flush(); + jlink_reset(trst, srst); + return jlink_flush(); +} + COMMAND_HANDLER(jlink_usb_command) { int tmp; @@ -2283,6 +2278,7 @@ struct jtag_interface jlink_interface = { .khz = &jlink_khz, .init = &jlink_init, .quit = &jlink_quit, + .reset = &jlink_reset_safe, .config_trace = &config_trace, .poll_trace = &poll_trace, }; diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index e3ad84d30..dcca8a0e8 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -819,11 +819,16 @@ static void kitprog_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data) /*************** jtag lowlevel functions ********************/ -static void kitprog_execute_reset(struct jtag_command *cmd) +static int kitprog_reset(int trst, int srst) { int retval = ERROR_OK; - if (cmd->cmd.reset->srst == 1) { + if (trst == 1) { + LOG_ERROR("KitProg: Interface has no TRST"); + return ERROR_FAIL; + } + + if (srst == 1) { retval = kitprog_reset_target(); /* Since the previous command also disables SWCLK output, we need to send an * SWD bus reset command to re-enable it. For some reason, running @@ -836,6 +841,7 @@ static void kitprog_execute_reset(struct jtag_command *cmd) if (retval != ERROR_OK) LOG_ERROR("KitProg: Interface reset failed"); + return retval; } static void kitprog_execute_sleep(struct jtag_command *cmd) @@ -846,9 +852,6 @@ static void kitprog_execute_sleep(struct jtag_command *cmd) static void kitprog_execute_command(struct jtag_command *cmd) { switch (cmd->type) { - case JTAG_RESET: - kitprog_execute_reset(cmd); - break; case JTAG_SLEEP: kitprog_execute_sleep(cmd); break; @@ -968,5 +971,6 @@ struct jtag_interface kitprog_interface = { .swd = &kitprog_swd, .execute_queue = kitprog_execute_queue, .init = kitprog_init, - .quit = kitprog_quit + .quit = kitprog_quit, + .reset = kitprog_reset, }; diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index c6ffa3205..706300005 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -560,12 +560,12 @@ struct jtag_interface sysfsgpio_interface = { .commands = sysfsgpio_command_handlers, .init = sysfsgpio_init, .quit = sysfsgpio_quit, + .reset = sysfsgpio_reset, }; static struct bitbang_interface sysfsgpio_bitbang = { .read = sysfsgpio_read, .write = sysfsgpio_write, - .reset = sysfsgpio_reset, .swdio_read = sysfsgpio_swdio_read, .swdio_drive = sysfsgpio_swdio_drive, .blink = 0 diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index 4907ef0e2..5dd1bca40 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -59,7 +59,7 @@ static void vsllink_runtest(int num_cycles); static void vsllink_stableclocks(int num_cycles, int tms); static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command); -static void vsllink_reset(int trst, int srst); +static int vsllink_reset(int trst, int srst); /* VSLLink tap buffer functions */ static void vsllink_tap_append_step(int tms, int tdi); @@ -164,20 +164,6 @@ static int vsllink_execute_queue(void) cmd->cmd.scan); break; - case JTAG_RESET: - LOG_DEBUG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - - vsllink_tap_execute(); - - if (cmd->cmd.reset->trst == 1) - tap_set_state(TAP_RESET); - - vsllink_reset(cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - break; - case JTAG_SLEEP: LOG_DEBUG_IO("sleep %i", cmd->cmd.sleep->us); vsllink_tap_execute(); @@ -478,7 +464,7 @@ static void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, vsllink_state_move(); } -static void vsllink_reset(int trst, int srst) +static int vsllink_reset(int trst, int srst) { LOG_DEBUG("trst: %i, srst: %i", trst, srst); @@ -494,7 +480,7 @@ static void vsllink_reset(int trst, int srst) versaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0); } - versaloon_interface.adaptors.peripheral_commit(); + return versaloon_interface.adaptors.peripheral_commit(); } COMMAND_HANDLER(vsllink_handle_usb_vid_command) @@ -971,6 +957,7 @@ struct jtag_interface vsllink_interface = { .init = vsllink_init, .quit = vsllink_quit, + .reset = vsllink_reset, .khz = vsllink_khz, .speed = vsllink_speed, .speed_div = vsllink_speed_div, diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index f25023ba7..f0899246b 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -1592,35 +1592,44 @@ static void xds110_flush(void) xds110.txn_result_count = 0; } -static void xds110_execute_reset(struct jtag_command *cmd) +static int xds110_reset(int trst, int srst) { - char trst; - char srst; + uint8_t value; + bool success; + int retval = ERROR_OK; - if (cmd->cmd.reset->trst != -1) { - if (cmd->cmd.reset->trst == 0) { + if (trst != -1) { + if (trst == 0) { /* Deassert nTRST (active low) */ - trst = 1; + value = 1; } else { /* Assert nTRST (active low) */ - trst = 0; + value = 0; } - (void)xds_set_trst(trst); + success = xds_set_trst(value); + if (!success) + retval = ERROR_FAIL; } - if (cmd->cmd.reset->srst != -1) { - if (cmd->cmd.reset->srst == 0) { + if (srst != -1) { + if (srst == 0) { /* Deassert nSRST (active low) */ - srst = 1; + value = 1; } else { /* Assert nSRST (active low) */ - srst = 0; + value = 0; } - (void)xds_set_srst(srst); + success = xds_set_srst(value); + if (!success) + retval = ERROR_FAIL; /* Toggle TCK to trigger HIB on CC13x/CC26x devices */ - (void)xds_cycle_tck(60000); + success = xds_cycle_tck(60000); + if (!success) + retval = ERROR_FAIL; } + + return retval; } static void xds110_execute_sleep(struct jtag_command *cmd) @@ -1788,10 +1797,6 @@ static void xds110_queue_stableclocks(struct jtag_command *cmd) static void xds110_execute_command(struct jtag_command *cmd) { switch (cmd->type) { - case JTAG_RESET: - xds110_flush(); - xds110_execute_reset(cmd); - break; case JTAG_SLEEP: xds110_flush(); xds110_execute_sleep(cmd); @@ -2045,4 +2050,5 @@ struct jtag_interface xds110_interface = { .khz = xds110_khz, .init = xds110_init, .quit = xds110_quit, + .reset = xds110_reset, }; diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 410eef980..6e4237afc 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -246,6 +246,20 @@ struct jtag_interface { */ int (*quit)(void); + /** + * Control (assert/deassert) the signals SRST and TRST on the interface. + * This function is optional. + * Adapters that don't support resets can either not define this function + * or return an error code. + * Adapters that don't support one of the two reset should ignore the + * request to assert the missing signal and eventually log an error. + * + * @param srst 1 to assert SRST, 0 to deassert SRST. + * @param trst 1 to assert TRST, 0 to deassert TRST. + * @returns ERROR_OK on success, or an error code on failure. + */ + int (*reset)(int srst, int trst); + /** * Returns JTAG maxium speed for KHz. 0 = RTCK. The function returns * a failure if it can't support the KHz/RTCK. diff --git a/src/jtag/swd.h b/src/jtag/swd.h index 0d1702c73..487cb85bf 100644 --- a/src/jtag/swd.h +++ b/src/jtag/swd.h @@ -277,6 +277,5 @@ struct swd_driver { }; int swd_init_reset(struct command_context *cmd_ctx); -void swd_add_reset(int req_srst); #endif /* OPENOCD_JTAG_SWD_H */ diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index a3735661b..68a50b189 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -112,7 +112,7 @@ static int swd_connect(struct adiv5_dap *dap) if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { if (jtag_reset_config & RESET_SRST_NO_GATING) - swd_add_reset(1); + adapter_assert_reset(); else LOG_WARNING("\'srst_nogate\' reset_config option is required"); } From 9daec098a9011171335f0a60536593dcceb9ce5b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 4 Sep 2019 16:47:24 +0200 Subject: [PATCH 067/354] bitbang: jtag-only drivers: switch to new reset API Remove the JTAG_RESET command from the bitbang execute queue now that all bitbang drivers have moved away from old reset method. Remove also the internal reset API in struct bitbang_interface. Tested parport only. Change-Id: I12b157ef442f4c9912406b19b7a4d32ba6ec0b53 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5300 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/drivers/at91rm9200.c | 3 +-- src/jtag/drivers/bitbang.c | 11 ----------- src/jtag/drivers/bitbang.h | 1 - src/jtag/drivers/dummy.c | 2 +- src/jtag/drivers/ep93xx.c | 2 +- src/jtag/drivers/parport.c | 2 +- src/jtag/drivers/remote_bitbang.c | 2 +- 7 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/jtag/drivers/at91rm9200.c b/src/jtag/drivers/at91rm9200.c index ac655635d..e2f64f53b 100644 --- a/src/jtag/drivers/at91rm9200.c +++ b/src/jtag/drivers/at91rm9200.c @@ -111,7 +111,6 @@ static uint32_t *pio_base; */ static bb_value_t at91rm9200_read(void); static int at91rm9200_write(int tck, int tms, int tdi); -static int at91rm9200_reset(int trst, int srst); static int at91rm9200_init(void); static int at91rm9200_quit(void); @@ -119,7 +118,6 @@ static int at91rm9200_quit(void); static struct bitbang_interface at91rm9200_bitbang = { .read = at91rm9200_read, .write = at91rm9200_write, - .reset = at91rm9200_reset, .blink = 0 }; @@ -196,6 +194,7 @@ struct jtag_interface at91rm9200_interface = { .commands = at91rm9200_command_handlers, .init = at91rm9200_init, .quit = at91rm9200_quit, + .reset = at91rm9200_reset, }; static int at91rm9200_init(void) diff --git a/src/jtag/drivers/bitbang.c b/src/jtag/drivers/bitbang.c index b5078c080..72e9320b4 100644 --- a/src/jtag/drivers/bitbang.c +++ b/src/jtag/drivers/bitbang.c @@ -314,17 +314,6 @@ int bitbang_execute_queue(void) while (cmd) { switch (cmd->type) { - case JTAG_RESET: - LOG_DEBUG_IO("reset trst: %i srst %i", - cmd->cmd.reset->trst, - cmd->cmd.reset->srst); - if ((cmd->cmd.reset->trst == 1) || - (cmd->cmd.reset->srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) - tap_set_state(TAP_RESET); - if (bitbang_interface->reset(cmd->cmd.reset->trst, - cmd->cmd.reset->srst) != ERROR_OK) - return ERROR_FAIL; - break; case JTAG_RUNTEST: LOG_DEBUG_IO("runtest %i cycles, end in %s", cmd->cmd.runtest->num_cycles, diff --git a/src/jtag/drivers/bitbang.h b/src/jtag/drivers/bitbang.h index 577717ebd..edb779cad 100644 --- a/src/jtag/drivers/bitbang.h +++ b/src/jtag/drivers/bitbang.h @@ -51,7 +51,6 @@ struct bitbang_interface { /** Set TCK, TMS, and TDI to the given values. */ int (*write)(int tck, int tms, int tdi); - int (*reset)(int trst, int srst); int (*blink)(int on); int (*swdio_read)(void); void (*swdio_drive)(bool on); diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c index 4e5b6152c..739213e23 100644 --- a/src/jtag/drivers/dummy.c +++ b/src/jtag/drivers/dummy.c @@ -91,7 +91,6 @@ static int dummy_led(int on) static struct bitbang_interface dummy_bitbang = { .read = &dummy_read, .write = &dummy_write, - .reset = &dummy_reset, .blink = &dummy_led, }; @@ -160,4 +159,5 @@ struct jtag_interface dummy_interface = { .init = &dummy_init, .quit = &dummy_quit, + .reset = &dummy_reset, }; diff --git a/src/jtag/drivers/ep93xx.c b/src/jtag/drivers/ep93xx.c index 4cf318485..dbbfc7ac6 100644 --- a/src/jtag/drivers/ep93xx.c +++ b/src/jtag/drivers/ep93xx.c @@ -59,12 +59,12 @@ struct jtag_interface ep93xx_interface = { .init = ep93xx_init, .quit = ep93xx_quit, + .reset = ep93xx_reset, }; static struct bitbang_interface ep93xx_bitbang = { .read = ep93xx_read, .write = ep93xx_write, - .reset = ep93xx_reset, .blink = 0, }; diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c index 8e44dcb79..3a589a3a5 100644 --- a/src/jtag/drivers/parport.c +++ b/src/jtag/drivers/parport.c @@ -260,7 +260,6 @@ static int parport_get_giveio_access(void) static struct bitbang_interface parport_bitbang = { .read = &parport_read, .write = &parport_write, - .reset = &parport_reset, .blink = &parport_led, }; @@ -522,6 +521,7 @@ struct jtag_interface parport_interface = { .init = parport_init, .quit = parport_quit, + .reset = parport_reset, .khz = parport_khz, .speed_div = parport_speed_div, .speed = parport_speed, diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c index a35489487..70280d23e 100644 --- a/src/jtag/drivers/remote_bitbang.c +++ b/src/jtag/drivers/remote_bitbang.c @@ -199,7 +199,6 @@ static struct bitbang_interface remote_bitbang_bitbang = { .sample = &remote_bitbang_sample, .read_sample = &remote_bitbang_read_sample, .write = &remote_bitbang_write, - .reset = &remote_bitbang_reset, .blink = &remote_bitbang_blink, }; @@ -349,4 +348,5 @@ struct jtag_interface remote_bitbang_interface = { .commands = remote_bitbang_command_handlers, .init = &remote_bitbang_init, .quit = &remote_bitbang_quit, + .reset = &remote_bitbang_reset, }; From 0f24549ce95e682f1e04b3358b13ea8b7f80c074 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 6 Sep 2019 11:00:19 +0200 Subject: [PATCH 068/354] hla: use the new system_reset API HLA uses its own internal driver's API to control the adapter's system reset, but at the same time it calls jtag_add_reset() to avoid breaking the internal logic of OpenOCD. This implicitly forces HLA to rely on jtag queue mechanism, even if HLA has no link with JTAG state machine. It requires HLA to implement an empty execute_queue() to comply with the JTAG queue. Modify the HLA framework and the HLA targets to use the new adapter API for system_reset and decouple HLA from JTAG queue. Rename the HLA static functions adapter_assert_reset() and adapter_deassert_reset() to avoid overlap with the global functions with same name. While there, fix a minor typo in a comment s/incase/in case/. Do not remove from HLA the JTAG specific API execute_queue(), even if not required anymore, because OpenOCD code still has calls to jtag_execute_queue() in case of non JTAG transport. Change-Id: I0e65e3e557bd665bd3d3aeaa84ea609b55a05e48 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4896 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/core.c | 37 ++++++++++++++---------------------- src/jtag/hla/hla_interface.c | 28 +++++++++------------------ src/jtag/hla/hla_interface.h | 9 --------- src/jtag/interface.h | 4 ++-- src/target/hla_target.c | 24 ++++++++--------------- src/target/stm8.c | 14 +++----------- 6 files changed, 36 insertions(+), 80 deletions(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index 97caeb18a..69553ebaf 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -35,8 +35,6 @@ #include "interface.h" #include #include -#include -#include #ifdef HAVE_STRINGS_H #include @@ -2009,19 +2007,7 @@ int adapter_resets(int trst, int srst) /* adapters without trst signal will eventually use tlr sequence */ jtag_add_reset(trst, srst); return ERROR_OK; - } else if (transport_is_swd()) { - if (trst == TRST_ASSERT) { - LOG_ERROR("transport swd has no trst signal"); - return ERROR_FAIL; - } - - if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) { - LOG_ERROR("adapter has no srst signal"); - return ERROR_FAIL; - } - adapter_system_reset(srst); - return ERROR_OK; - } else if (transport_is_hla()) { + } else if (transport_is_swd() || transport_is_hla()) { if (trst == TRST_ASSERT) { LOG_ERROR("transport %s has no trst signal", get_current_transport()->name); @@ -2032,7 +2018,8 @@ int adapter_resets(int trst, int srst) LOG_ERROR("adapter has no srst signal"); return ERROR_FAIL; } - return hl_interface_reset(srst); + adapter_system_reset(srst); + return ERROR_OK; } if (trst == TRST_DEASSERT && srst == SRST_DEASSERT) @@ -2044,33 +2031,37 @@ int adapter_resets(int trst, int srst) return ERROR_FAIL; } -void adapter_assert_reset(void) +int adapter_assert_reset(void) { if (transport_is_jtag()) { if (jtag_reset_config & RESET_SRST_PULLS_TRST) jtag_add_reset(1, 1); else jtag_add_reset(0, 1); - } else if (transport_is_swd()) - adapter_system_reset(1); + return ERROR_OK; + } else if (transport_is_swd() || transport_is_hla()) + return adapter_system_reset(1); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", get_current_transport()->name); else LOG_ERROR("transport is not selected"); + return ERROR_FAIL; } -void adapter_deassert_reset(void) +int adapter_deassert_reset(void) { - if (transport_is_jtag()) + if (transport_is_jtag()) { jtag_add_reset(0, 0); - else if (transport_is_swd()) - adapter_system_reset(0); + return ERROR_OK; + } else if (transport_is_swd() || transport_is_hla()) + return adapter_system_reset(0); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", get_current_transport()->name); else LOG_ERROR("transport is not selected"); + return ERROR_FAIL; } int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index b50cb9c0f..5056741e1 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -127,6 +127,11 @@ static int hl_interface_quit(void) return ERROR_OK; } +static int hl_interface_reset(int req_trst, int req_srst) +{ + return hl_if.layout->api->assert_srst(hl_if.handle, req_srst ? 0 : 1); +} + static int hl_interface_execute_queue(void) { LOG_DEBUG("hl_interface_execute_queue: ignored"); @@ -136,33 +141,17 @@ static int hl_interface_execute_queue(void) int hl_interface_init_reset(void) { - /* incase the adapter has not already handled asserting srst + /* in case the adapter has not already handled asserting srst * we will attempt it again */ if (hl_if.param.connect_under_reset) { - jtag_add_reset(0, 1); - hl_if.layout->api->assert_srst(hl_if.handle, 0); + adapter_assert_reset(); } else { - jtag_add_reset(0, 0); + adapter_deassert_reset(); } return ERROR_OK; } -/* FIXME: hla abuses of jtag_add_reset() to track srst status and for timings */ -int hl_interface_reset(int srst) -{ - int result; - - if (srst == 1) { - jtag_add_reset(0, 1); - result = hl_if.layout->api->assert_srst(hl_if.handle, 0); - } else { - result = hl_if.layout->api->assert_srst(hl_if.handle, 1); - jtag_add_reset(0, 0); - } - return result; -} - static int hl_interface_khz(int khz, int *jtag_speed) { if (hl_if.layout->api->speed == NULL) @@ -371,6 +360,7 @@ struct jtag_interface hl_interface = { .transports = hl_transports, .init = hl_interface_init, .quit = hl_interface_quit, + .reset = hl_interface_reset, .execute_queue = hl_interface_execute_queue, .speed = &hl_interface_speed, .khz = &hl_interface_khz, diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h index 84b0098b6..262025e98 100644 --- a/src/jtag/hla/hla_interface.h +++ b/src/jtag/hla/hla_interface.h @@ -67,13 +67,4 @@ int hl_interface_init_target(struct target *t); int hl_interface_init_reset(void); int hl_interface_override_target(const char **targetname); -#if BUILD_HLADAPTER == 1 -int hl_interface_reset(int srst); -#else -static inline int hl_interface_reset(int srst) -{ - return ERROR_OK; -} -#endif - #endif /* OPENOCD_JTAG_HLA_HLA_INTERFACE_H */ diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 6e4237afc..c5579f5e0 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -341,8 +341,8 @@ struct jtag_interface { extern const char * const jtag_only[]; int adapter_resets(int assert_trst, int assert_srst); -void adapter_assert_reset(void); -void adapter_deassert_reset(void); +int adapter_assert_reset(void); +int adapter_deassert_reset(void); int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t port_size, unsigned int *trace_freq, unsigned int traceclkin_freq, uint16_t *prescaler); diff --git a/src/target/hla_target.c b/src/target/hla_target.c index 60ed7d64d..f0dc57276 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -25,6 +25,7 @@ #include "config.h" #endif +#include "jtag/interface.h" #include "jtag/jtag.h" #include "jtag/hla/hla_transport.h" #include "jtag/hla/hla_interface.h" @@ -499,7 +500,7 @@ static int adapter_poll(struct target *target) return ERROR_OK; } -static int adapter_assert_reset(struct target *target) +static int hl_assert_reset(struct target *target) { int res = ERROR_OK; struct hl_interface_s *adapter = target_to_adapter(target); @@ -514,8 +515,7 @@ static int adapter_assert_reset(struct target *target) if ((jtag_reset_config & RESET_HAS_SRST) && (jtag_reset_config & RESET_SRST_NO_GATING)) { - jtag_add_reset(0, 1); - res = adapter->layout->api->assert_srst(adapter->handle, 0); + res = adapter_assert_reset(); srst_asserted = true; } @@ -529,8 +529,7 @@ static int adapter_assert_reset(struct target *target) if (jtag_reset_config & RESET_HAS_SRST) { if (!srst_asserted) { - jtag_add_reset(0, 1); - res = adapter->layout->api->assert_srst(adapter->handle, 0); + res = adapter_assert_reset(); } if (res == ERROR_COMMAND_NOTFOUND) LOG_ERROR("Hardware srst not supported, falling back to software reset"); @@ -563,21 +562,14 @@ static int adapter_assert_reset(struct target *target) return ERROR_OK; } -static int adapter_deassert_reset(struct target *target) +static int hl_deassert_reset(struct target *target) { - struct hl_interface_s *adapter = target_to_adapter(target); - enum reset_types jtag_reset_config = jtag_get_reset_config(); LOG_DEBUG("%s", __func__); if (jtag_reset_config & RESET_HAS_SRST) - adapter->layout->api->assert_srst(adapter->handle, 1); - - /* virtual deassert reset, we need it for the internal - * jtag state machine - */ - jtag_add_reset(0, 0); + adapter_deassert_reset(); target->savedDCRDR = 0; /* clear both DCC busy bits on initial resume */ @@ -819,8 +811,8 @@ struct target_type hla_target = { .arch_state = armv7m_arch_state, .target_request_data = hl_target_request_data, - .assert_reset = adapter_assert_reset, - .deassert_reset = adapter_deassert_reset, + .assert_reset = hl_assert_reset, + .deassert_reset = hl_deassert_reset, .halt = adapter_halt, .resume = adapter_resume, diff --git a/src/target/stm8.c b/src/target/stm8.c index 144c797de..54a4bce26 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -25,6 +25,7 @@ #include "target.h" #include "target_type.h" #include "hello.h" +#include "jtag/interface.h" #include "jtag/jtag.h" #include "jtag/hla/hla_transport.h" #include "jtag/hla/hla_interface.h" @@ -930,9 +931,7 @@ static int stm8_reset_assert(struct target *target) enum reset_types jtag_reset_config = jtag_get_reset_config(); if (jtag_reset_config & RESET_HAS_SRST) { - jtag_add_reset(0, 1); - res = adapter->layout->api->assert_srst(adapter->handle, 0); - + res = adapter_assert_reset(); if (res == ERROR_OK) /* hardware srst supported */ use_srst_fallback = false; @@ -966,21 +965,14 @@ static int stm8_reset_assert(struct target *target) static int stm8_reset_deassert(struct target *target) { int res; - struct hl_interface_s *adapter = target_to_adapter(target); - enum reset_types jtag_reset_config = jtag_get_reset_config(); if (jtag_reset_config & RESET_HAS_SRST) { - res = adapter->layout->api->assert_srst(adapter->handle, 1); + res = adapter_deassert_reset(); if ((res != ERROR_OK) && (res != ERROR_COMMAND_NOTFOUND)) return res; } - /* virtual deassert reset, we need it for the internal - * jtag state machine - */ - jtag_add_reset(0, 0); - /* The cpu should now be stalled. If halt was requested let poll detect the stall */ if (target->reset_halt) From f275ae586bba359611dd34af2b3718526101279e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 28 Aug 2018 14:49:10 +0200 Subject: [PATCH 069/354] jtag: print an errmsg on using jtag API for non jtag transport After the cleanup of swd and hla, there should be no more calls to jtag_execute_queue() or to queue jtag commands if current transport is not jtag. Thus we can start removing the jtag specific code from adapters that do not support jtag. To prevent some remaining call to jtag_execute_queue() to crash openocd, verify the transport, print an error message if the transport is not jtag, call the adapter's jtag_execute_queue() only if it exist. To identify code that still add commands in the jtag queue even if transport is not jtag, print an error message in the function jtag_queue_command(). For the moment, still queue the message, even if will cause a memory leak if there is no following call to jtag_execute_queue(); the target is to identify the issue and cleanup the code, thus solving also the leak. Change-Id: I8fc85f754aa057aad1df05ff0448c8619897da23 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4897 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/commands.c | 14 ++++++++++++++ src/jtag/core.c | 13 +++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/jtag/commands.c b/src/jtag/commands.c index 3352e035a..e88a3b74f 100644 --- a/src/jtag/commands.c +++ b/src/jtag/commands.c @@ -31,6 +31,7 @@ #endif #include +#include #include "commands.h" struct cmd_queue_page { @@ -48,6 +49,19 @@ static struct jtag_command **next_command_pointer = &jtag_command_queue; void jtag_queue_command(struct jtag_command *cmd) { + if (!transport_is_jtag()) { + /* + * FIXME: This should not happen! + * There could be old code that queues jtag commands with non jtag interfaces so, for + * the moment simply highlight it by log an error. + * We should fix it quitting with assert(0) because it is an internal error, or returning + * an error after call to jtag_command_queue_reset() to free the jtag queue and avoid + * memory leaks. + * The fix can be applied immediately after next release (v0.11.0 ?) + */ + LOG_ERROR("JTAG API jtag_queue_command() called on non JTAG interface"); + } + /* this command goes on the end, so ensure the queue terminates */ cmd->next = NULL; diff --git a/src/jtag/core.c b/src/jtag/core.c index 69553ebaf..5e9777e74 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -937,6 +937,19 @@ int default_interface_jtag_execute_queue(void) return ERROR_FAIL; } + if (!transport_is_jtag()) { + /* + * FIXME: This should not happen! + * There could be old code that queues jtag commands with non jtag interfaces so, for + * the moment simply highlight it by log an error and return on empty execute_queue. + * We should fix it quitting with assert(0) because it is an internal error. + * The fix can be applied immediately after next release (v0.11.0 ?) + */ + LOG_ERROR("JTAG API jtag_execute_queue() called on non JTAG interface"); + if (!jtag->execute_queue) + return ERROR_OK; + } + int result = jtag->execute_queue(); #if !BUILD_ZY1000 From b5621bf2f971b30ebc0fe7fe62b2068e6f8e1adf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 14 Jan 2019 22:52:42 +0100 Subject: [PATCH 070/354] hla: remove empty JTAG execute_queue method We do not rely on JTAG queue anymore. Remove the remaining JTAG heritage. Change-Id: I6c87d9ffebaa383c998cf273188b3e7f28b3fe95 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4898 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/hla/hla_interface.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index 5056741e1..dbbebed3d 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -132,13 +132,6 @@ static int hl_interface_reset(int req_trst, int req_srst) return hl_if.layout->api->assert_srst(hl_if.handle, req_srst ? 0 : 1); } -static int hl_interface_execute_queue(void) -{ - LOG_DEBUG("hl_interface_execute_queue: ignored"); - - return ERROR_OK; -} - int hl_interface_init_reset(void) { /* in case the adapter has not already handled asserting srst @@ -355,13 +348,11 @@ static const struct command_registration hl_interface_command_handlers[] = { struct jtag_interface hl_interface = { .name = "hla", - .supported = 0, .commands = hl_interface_command_handlers, .transports = hl_transports, .init = hl_interface_init, .quit = hl_interface_quit, .reset = hl_interface_reset, - .execute_queue = hl_interface_execute_queue, .speed = &hl_interface_speed, .khz = &hl_interface_khz, .speed_div = &hl_interface_speed_div, From 7268ff22c399832ee09ca3216753f17473ae9fab Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 22 Jan 2019 01:31:42 +0100 Subject: [PATCH 071/354] drivers/kitprog: remove unused JTAG execute_queue method kitprog is SWD only and we do not rely on JTAG queue anymore. Remove the remaining JTAG heritage. Change-Id: Ic586278368301eb669bc6e4e641f683a81cb171d Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4899 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/drivers/kitprog.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index dcca8a0e8..a08f03642 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -844,35 +844,6 @@ static int kitprog_reset(int trst, int srst) return retval; } -static void kitprog_execute_sleep(struct jtag_command *cmd) -{ - jtag_sleep(cmd->cmd.sleep->us); -} - -static void kitprog_execute_command(struct jtag_command *cmd) -{ - switch (cmd->type) { - case JTAG_SLEEP: - kitprog_execute_sleep(cmd); - break; - default: - LOG_ERROR("BUG: unknown JTAG command type encountered"); - exit(-1); - } -} - -static int kitprog_execute_queue(void) -{ - struct jtag_command *cmd = jtag_command_queue; - - while (cmd != NULL) { - kitprog_execute_command(cmd); - cmd = cmd->next; - } - - return ERROR_OK; -} - COMMAND_HANDLER(kitprog_handle_info_command) { int retval = kitprog_get_info(); @@ -969,7 +940,6 @@ struct jtag_interface kitprog_interface = { .commands = kitprog_command_handlers, .transports = kitprog_transports, .swd = &kitprog_swd, - .execute_queue = kitprog_execute_queue, .init = kitprog_init, .quit = kitprog_quit, .reset = kitprog_reset, From efd1d642220a4f6d3b9a9607c186452b265400d2 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 22 Jan 2019 16:31:18 +0100 Subject: [PATCH 072/354] adapter: switch from struct jtag_interface to adapter_driver To reorganize the adapters code, introduce an adapter_driver struct that contains all the adapter generic part, while keeping in two separate struct the specific API jtag_ops and swd_ops. Move the allocation of *adapter_driver from the JTAG-specific file core.c to the more adapter-specific file adapter.c While splitting the old jtag_interface for every driver, put the fields in the same order as in the struct declaration so we keep a consistent code across all the drivers. While other transport specific API could/would be added as separate ops, nothing is done here for HLA. Change-Id: I2d60f97ac514c0dd2d93a6ec9be66fd9d388dad5 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4900 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/adapter.c | 22 ++-- src/jtag/aice/aice_interface.c | 14 ++- src/jtag/core.c | 18 +-- src/jtag/drivers/amt_jtagaccel.c | 9 +- src/jtag/drivers/arm-jtag-ew.c | 20 +-- src/jtag/drivers/at91rm9200.c | 10 +- src/jtag/drivers/bcm2835gpio.c | 18 ++- src/jtag/drivers/buspirate.c | 14 ++- src/jtag/drivers/cmsis_dap_usb.c | 23 ++-- src/jtag/drivers/dummy.c | 30 ++--- src/jtag/drivers/ep93xx.c | 10 +- src/jtag/drivers/ft232r.c | 18 +-- src/jtag/drivers/ftdi.c | 17 ++- src/jtag/drivers/gw16012.c | 9 +- src/jtag/drivers/imx_gpio.c | 18 ++- src/jtag/drivers/jlink.c | 22 ++-- src/jtag/drivers/jtag_vpi.c | 13 +- src/jtag/drivers/kitprog.c | 8 +- src/jtag/drivers/opendous.c | 10 +- src/jtag/drivers/openjtag.c | 17 +-- src/jtag/drivers/osbdm.c | 14 ++- src/jtag/drivers/parport.c | 13 +- src/jtag/drivers/presto.c | 13 +- src/jtag/drivers/remote_bitbang.c | 10 +- src/jtag/drivers/rlink.c | 12 +- src/jtag/drivers/sysfsgpio.c | 12 +- src/jtag/drivers/ulink.c | 25 ++-- src/jtag/drivers/usb_blaster/usb_blaster.c | 11 +- src/jtag/drivers/usbprog.c | 11 +- src/jtag/drivers/vsllink.c | 17 ++- src/jtag/drivers/xds110.c | 23 ++-- src/jtag/hla/hla_interface.c | 7 +- src/jtag/interface.h | 43 ++++--- src/jtag/interfaces.c | 138 ++++++++++----------- src/jtag/interfaces.h | 6 +- src/jtag/minidummy/minidummy.c | 12 +- src/jtag/zy1000/zy1000.c | 12 +- src/target/adi_v5_swd.c | 6 +- src/target/arm_dap.c | 4 +- 39 files changed, 441 insertions(+), 268 deletions(-) diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index d23f79ec4..e2782a777 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -46,7 +46,7 @@ * Holds support for configuring debug adapters from TCl scripts. */ -extern struct jtag_interface *jtag_interface; +struct adapter_driver *adapter_driver; const char * const jtag_only[] = { "jtag", NULL }; static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) @@ -61,7 +61,7 @@ static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)"); return JIM_ERR; } - const char *name = jtag_interface ? jtag_interface->name : NULL; + const char *name = adapter_driver ? adapter_driver->name : NULL; Jim_SetResultString(goi.interp, name ? : "undefined", -1); return JIM_OK; } @@ -91,8 +91,8 @@ COMMAND_HANDLER(handle_interface_list_command) return ERROR_COMMAND_SYNTAX_ERROR; command_print(CMD, "The following debug interfaces are available:"); - for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) { - const char *name = jtag_interfaces[i]->name; + for (unsigned i = 0; NULL != adapter_drivers[i]; i++) { + const char *name = adapter_drivers[i]->name; command_print(CMD, "%u: %s", i + 1, name); } @@ -104,7 +104,7 @@ COMMAND_HANDLER(handle_interface_command) int retval; /* check whether the interface is already configured */ - if (jtag_interface) { + if (adapter_driver) { LOG_WARNING("Interface already configured, ignoring"); return ERROR_OK; } @@ -113,20 +113,20 @@ COMMAND_HANDLER(handle_interface_command) if (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\0') return ERROR_COMMAND_SYNTAX_ERROR; - for (unsigned i = 0; NULL != jtag_interfaces[i]; i++) { - if (strcmp(CMD_ARGV[0], jtag_interfaces[i]->name) != 0) + for (unsigned i = 0; NULL != adapter_drivers[i]; i++) { + if (strcmp(CMD_ARGV[0], adapter_drivers[i]->name) != 0) continue; - if (NULL != jtag_interfaces[i]->commands) { + if (NULL != adapter_drivers[i]->commands) { retval = register_commands(CMD_CTX, NULL, - jtag_interfaces[i]->commands); + adapter_drivers[i]->commands); if (ERROR_OK != retval) return retval; } - jtag_interface = jtag_interfaces[i]; + adapter_driver = adapter_drivers[i]; - return allow_transports(CMD_CTX, jtag_interface->transports); + return allow_transports(CMD_CTX, adapter_driver->transports); } /* no valid interface was found (i.e. the configuration option, diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c index c83b8c298..f9bd87eeb 100644 --- a/src/jtag/aice/aice_interface.c +++ b/src/jtag/aice/aice_interface.c @@ -518,14 +518,20 @@ static const struct command_registration aice_command_handlers[] = { /***************************************************************************/ /* End of Command handlers */ -struct jtag_interface aice_interface = { +static struct jtag_interface aice_interface = { + .execute_queue = aice_execute_queue, +}; + +struct adapter_driver aice_adapter_driver = { .name = "aice", - .commands = aice_command_handlers, .transports = aice_transports, + .commands = aice_command_handlers, + .init = aice_init, .quit = aice_quit, - .execute_queue = aice_execute_queue, .speed = aice_speed, /* set interface speed */ - .speed_div = aice_speed_div, /* return readable value */ .khz = aice_khz, /* convert khz to interface speed value */ + .speed_div = aice_speed_div, /* return readable value */ + + .jtag_ops = &aice_interface, }; diff --git a/src/jtag/core.c b/src/jtag/core.c index 5e9777e74..6239573d1 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -126,10 +126,10 @@ static int rclk_fallback_speed_khz; static enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode; static int jtag_speed; -static struct jtag_interface *jtag; +/* FIXME: change name to this variable, it is not anymore JTAG only */ +static struct adapter_driver *jtag; -/* configuration */ -struct jtag_interface *jtag_interface; +extern struct adapter_driver *adapter_driver; void jtag_set_flush_queue_sleep(int ms) { @@ -503,7 +503,7 @@ int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state) { int retval; - if (!(jtag->supported & DEBUG_CAP_TMS_SEQ)) + if (!(jtag->jtag_ops->supported & DEBUG_CAP_TMS_SEQ)) return ERROR_JTAG_NOT_IMPLEMENTED; jtag_checks(); @@ -946,11 +946,11 @@ int default_interface_jtag_execute_queue(void) * The fix can be applied immediately after next release (v0.11.0 ?) */ LOG_ERROR("JTAG API jtag_execute_queue() called on non JTAG interface"); - if (!jtag->execute_queue) + if (!jtag->jtag_ops || !jtag->jtag_ops->execute_queue) return ERROR_OK; } - int result = jtag->execute_queue(); + int result = jtag->jtag_ops->execute_queue(); #if !BUILD_ZY1000 /* Only build this if we use a regular driver with a command queue. @@ -1518,7 +1518,7 @@ int adapter_init(struct command_context *cmd_ctx) if (jtag) return ERROR_OK; - if (!jtag_interface) { + if (!adapter_driver) { /* nothing was previously specified by "interface" command */ LOG_ERROR("Debug Adapter has to be specified, " "see \"interface\" command"); @@ -1526,10 +1526,10 @@ int adapter_init(struct command_context *cmd_ctx) } int retval; - retval = jtag_interface->init(); + retval = adapter_driver->init(); if (retval != ERROR_OK) return retval; - jtag = jtag_interface; + jtag = adapter_driver; if (jtag->speed == NULL) { LOG_INFO("This adapter doesn't support configurable speed"); diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c index 045672f0e..db106bb05 100644 --- a/src/jtag/drivers/amt_jtagaccel.c +++ b/src/jtag/drivers/amt_jtagaccel.c @@ -584,7 +584,11 @@ static const struct command_registration amtjtagaccel_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface amt_jtagaccel_interface = { +static struct jtag_interface amt_jtagaccel_interface = { + .execute_queue = amt_jtagaccel_execute_queue, +}; + +struct adapter_driver amt_jtagaccel_adapter_driver = { .name = "amt_jtagaccel", .transports = jtag_only, .commands = amtjtagaccel_command_handlers, @@ -592,5 +596,6 @@ struct jtag_interface amt_jtagaccel_interface = { .init = amt_jtagaccel_init, .quit = amt_jtagaccel_quit, .speed = amt_jtagaccel_speed, - .execute_queue = amt_jtagaccel_execute_queue, + + .jtag_ops = &amt_jtagaccel_interface, }; diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c index 285bf9b7f..c81f8043b 100644 --- a/src/jtag/drivers/arm-jtag-ew.c +++ b/src/jtag/drivers/arm-jtag-ew.c @@ -495,16 +495,22 @@ static const struct command_registration armjtagew_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface armjtagew_interface = { - .name = "arm-jtag-ew", - .commands = armjtagew_command_handlers, - .transports = jtag_only, +static struct jtag_interface armjtagew_interface = { .execute_queue = armjtagew_execute_queue, - .speed = armjtagew_speed, - .speed_div = armjtagew_speed_div, - .khz = armjtagew_khz, +}; + +struct adapter_driver armjtagew_adapter_driver = { + .name = "arm-jtag-ew", + .transports = jtag_only, + .commands = armjtagew_command_handlers, + .init = armjtagew_init, .quit = armjtagew_quit, + .speed = armjtagew_speed, + .khz = armjtagew_khz, + .speed_div = armjtagew_speed_div, + + .jtag_ops = &armjtagew_interface, }; /************************************************************************** diff --git a/src/jtag/drivers/at91rm9200.c b/src/jtag/drivers/at91rm9200.c index e2f64f53b..1026847fe 100644 --- a/src/jtag/drivers/at91rm9200.c +++ b/src/jtag/drivers/at91rm9200.c @@ -187,14 +187,20 @@ static const struct command_registration at91rm9200_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface at91rm9200_interface = { - .name = "at91rm9200", +static struct jtag_interface at91rm9200_interface = { .execute_queue = bitbang_execute_queue, +}; + +struct adapter_driver at91rm9200_adapter_driver = { + .name = "at91rm9200", .transports = jtag_only, .commands = at91rm9200_command_handlers, + .init = at91rm9200_init, .quit = at91rm9200_quit, .reset = at91rm9200_reset, + + .jtag_ops = &at91rm9200_interface, }; static int at91rm9200_init(void) diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c index 60316f17d..bbc87d3dd 100644 --- a/src/jtag/drivers/bcm2835gpio.c +++ b/src/jtag/drivers/bcm2835gpio.c @@ -405,19 +405,25 @@ static const struct command_registration bcm2835gpio_command_handlers[] = { static const char * const bcm2835_transports[] = { "jtag", "swd", NULL }; -struct jtag_interface bcm2835gpio_interface = { - .name = "bcm2835gpio", +static struct jtag_interface bcm2835gpio_interface = { .supported = DEBUG_CAP_TMS_SEQ, .execute_queue = bitbang_execute_queue, +}; + +struct adapter_driver bcm2835gpio_adapter_driver = { + .name = "bcm2835gpio", .transports = bcm2835_transports, - .swd = &bitbang_swd, - .speed = bcm2835gpio_speed, - .khz = bcm2835gpio_khz, - .speed_div = bcm2835gpio_speed_div, .commands = bcm2835gpio_command_handlers, + .init = bcm2835gpio_init, .quit = bcm2835gpio_quit, .reset = bcm2835gpio_reset, + .speed = bcm2835gpio_speed, + .khz = bcm2835gpio_khz, + .speed_div = bcm2835gpio_speed_div, + + .jtag_ops = &bcm2835gpio_interface, + .swd_ops = &bitbang_swd, }; static bool bcm2835gpio_jtag_mode_possible(void) diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c index 23d1547a9..020c4ce39 100644 --- a/src/jtag/drivers/buspirate.c +++ b/src/jtag/drivers/buspirate.c @@ -536,15 +536,21 @@ static const struct swd_driver buspirate_swd = { static const char * const buspirate_transports[] = { "jtag", "swd", NULL }; -struct jtag_interface buspirate_interface = { - .name = "buspirate", +static struct jtag_interface buspirate_interface = { .execute_queue = buspirate_execute_queue, - .commands = buspirate_command_handlers, +}; + +struct adapter_driver buspirate_adapter_driver = { + .name = "buspirate", .transports = buspirate_transports, - .swd = &buspirate_swd, + .commands = buspirate_command_handlers, + .init = buspirate_init, .quit = buspirate_quit, .reset = buspirate_reset, + + .jtag_ops = &buspirate_interface, + .swd_ops = &buspirate_swd, }; /*************** jtag execute commands **********************/ diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c index c54b70c7d..c0728214c 100644 --- a/src/jtag/drivers/cmsis_dap_usb.c +++ b/src/jtag/drivers/cmsis_dap_usb.c @@ -1786,18 +1786,23 @@ static const struct swd_driver cmsis_dap_swd_driver = { static const char * const cmsis_dap_transport[] = { "swd", "jtag", NULL }; -struct jtag_interface cmsis_dap_interface = { - .name = "cmsis-dap", +static struct jtag_interface cmsis_dap_interface = { .supported = DEBUG_CAP_TMS_SEQ, - .commands = cmsis_dap_command_handlers, - .swd = &cmsis_dap_swd_driver, - .transports = cmsis_dap_transport, - .execute_queue = cmsis_dap_execute_queue, - .speed = cmsis_dap_speed, - .speed_div = cmsis_dap_speed_div, - .khz = cmsis_dap_khz, +}; + +struct adapter_driver cmsis_dap_adapter_driver = { + .name = "cmsis-dap", + .transports = cmsis_dap_transport, + .commands = cmsis_dap_command_handlers, + .init = cmsis_dap_init, .quit = cmsis_dap_quit, .reset = cmsis_dap_reset, + .speed = cmsis_dap_speed, + .khz = cmsis_dap_khz, + .speed_div = cmsis_dap_speed_div, + + .jtag_ops = &cmsis_dap_interface, + .swd_ops = &cmsis_dap_swd_driver, }; diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c index 739213e23..e66cb6bd5 100644 --- a/src/jtag/drivers/dummy.c +++ b/src/jtag/drivers/dummy.c @@ -144,20 +144,22 @@ static const struct command_registration dummy_command_handlers[] = { /* The dummy driver is used to easily check the code path * where the target is unresponsive. */ -struct jtag_interface dummy_interface = { - .name = "dummy", +static struct jtag_interface dummy_interface = { + .supported = DEBUG_CAP_TMS_SEQ, + .execute_queue = &bitbang_execute_queue, +}; - .supported = DEBUG_CAP_TMS_SEQ, - .commands = dummy_command_handlers, - .transports = jtag_only, +struct adapter_driver dummy_adapter_driver = { + .name = "dummy", + .transports = jtag_only, + .commands = dummy_command_handlers, - .execute_queue = &bitbang_execute_queue, + .init = &dummy_init, + .quit = &dummy_quit, + .reset = &dummy_reset, + .speed = &dummy_speed, + .khz = &dummy_khz, + .speed_div = &dummy_speed_div, - .speed = &dummy_speed, - .khz = &dummy_khz, - .speed_div = &dummy_speed_div, - - .init = &dummy_init, - .quit = &dummy_quit, - .reset = &dummy_reset, - }; + .jtag_ops = &dummy_interface, +}; diff --git a/src/jtag/drivers/ep93xx.c b/src/jtag/drivers/ep93xx.c index dbbfc7ac6..5e0e62afa 100644 --- a/src/jtag/drivers/ep93xx.c +++ b/src/jtag/drivers/ep93xx.c @@ -50,16 +50,20 @@ static int ep93xx_quit(void); struct timespec ep93xx_zzzz; -struct jtag_interface ep93xx_interface = { - .name = "ep93xx", - +static struct jtag_interface ep93xx_interface = { .supported = DEBUG_CAP_TMS_SEQ, .execute_queue = bitbang_execute_queue, +}; + +struct adapter_driver ep93xx_adapter_driver = { + .name = "ep93xx", .transports = jtag_only, .init = ep93xx_init, .quit = ep93xx_quit, .reset = ep93xx_reset, + + .jtag_ops = &ep93xx_interface, }; static struct bitbang_interface ep93xx_bitbang = { diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index 8cda76ed2..1ef0c57ea 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -914,17 +914,21 @@ static int syncbb_execute_queue(void) return retval; } -struct jtag_interface ft232r_interface = { - .name = "ft232r", - .commands = ft232r_command_handlers, - .transports = jtag_only, +static struct jtag_interface ft232r_interface = { .supported = DEBUG_CAP_TMS_SEQ, - .execute_queue = syncbb_execute_queue, +}; + +struct adapter_driver ft232r_adapter_driver = { + .name = "ft232r", + .transports = jtag_only, + .commands = ft232r_command_handlers, - .speed = ft232r_speed, .init = ft232r_init, .quit = ft232r_quit, - .speed_div = ft232r_speed_div, + .speed = ft232r_speed, .khz = ft232r_khz, + .speed_div = ft232r_speed_div, + + .jtag_ops = &ft232r_interface, }; diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index e645e9fae..40d076ecf 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -1231,18 +1231,23 @@ static const struct swd_driver ftdi_swd = { static const char * const ftdi_transports[] = { "jtag", "swd", NULL }; -struct jtag_interface ftdi_interface = { - .name = "ftdi", +static struct jtag_interface ftdi_interface = { .supported = DEBUG_CAP_TMS_SEQ, - .commands = ftdi_command_handlers, + .execute_queue = ftdi_execute_queue, +}; + +struct adapter_driver ftdi_adapter_driver = { + .name = "ftdi", .transports = ftdi_transports, - .swd = &ftdi_swd, + .commands = ftdi_command_handlers, .init = ftdi_initialize, .quit = ftdi_quit, .reset = ftdi_reset, .speed = ftdi_speed, - .speed_div = ftdi_speed_div, .khz = ftdi_khz, - .execute_queue = ftdi_execute_queue, + .speed_div = ftdi_speed_div, + + .jtag_ops = &ftdi_interface, + .swd_ops = &ftdi_swd, }; diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c index 6969e8b79..2e8dad896 100644 --- a/src/jtag/drivers/gw16012.c +++ b/src/jtag/drivers/gw16012.c @@ -521,12 +521,17 @@ static const struct command_registration gw16012_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface gw16012_interface = { +static struct jtag_interface gw16012_interface = { + .execute_queue = gw16012_execute_queue, +}; + +struct adapter_driver gw16012_adapter_driver = { .name = "gw16012", .transports = jtag_only, .commands = gw16012_command_handlers, .init = gw16012_init, .quit = gw16012_quit, - .execute_queue = gw16012_execute_queue, + + .jtag_ops = &gw16012_interface, }; diff --git a/src/jtag/drivers/imx_gpio.c b/src/jtag/drivers/imx_gpio.c index d677e8a7e..7dcfb6790 100644 --- a/src/jtag/drivers/imx_gpio.c +++ b/src/jtag/drivers/imx_gpio.c @@ -427,19 +427,25 @@ static const struct command_registration imx_gpio_command_handlers[] = { static const char * const imx_gpio_transports[] = { "jtag", "swd", NULL }; -struct jtag_interface imx_gpio_interface = { - .name = "imx_gpio", +static struct jtag_interface imx_gpio_interface = { .supported = DEBUG_CAP_TMS_SEQ, .execute_queue = bitbang_execute_queue, +}; + +struct adapter_driver imx_gpio_adapter_driver = { + .name = "imx_gpio", .transports = imx_gpio_transports, - .swd = &bitbang_swd, - .speed = imx_gpio_speed, - .khz = imx_gpio_khz, - .speed_div = imx_gpio_speed_div, .commands = imx_gpio_command_handlers, + .init = imx_gpio_init, .quit = imx_gpio_quit, .reset = imx_gpio_reset, + .speed = imx_gpio_speed, + .khz = imx_gpio_khz, + .speed_div = imx_gpio_speed_div, + + .jtag_ops = &imx_gpio_interface, + .swd_ops = &bitbang_swd, }; static bool imx_gpio_jtag_mode_possible(void) diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 402ff9917..3dcadc813 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -2267,18 +2267,24 @@ static const struct swd_driver jlink_swd = { static const char * const jlink_transports[] = { "jtag", "swd", NULL }; -struct jtag_interface jlink_interface = { - .name = "jlink", - .commands = jlink_command_handlers, - .transports = jlink_transports, - .swd = &jlink_swd, +static struct jtag_interface jlink_interface = { .execute_queue = &jlink_execute_queue, - .speed = &jlink_speed, - .speed_div = &jlink_speed_div, - .khz = &jlink_khz, +}; + +struct adapter_driver jlink_adapter_driver = { + .name = "jlink", + .transports = jlink_transports, + .commands = jlink_command_handlers, + .init = &jlink_init, .quit = &jlink_quit, .reset = &jlink_reset_safe, + .speed = &jlink_speed, + .khz = &jlink_khz, + .speed_div = &jlink_speed_div, .config_trace = &config_trace, .poll_trace = &poll_trace, + + .jtag_ops = &jlink_interface, + .swd_ops = &jlink_swd, }; diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c index 7ac7e962f..e5124b5b0 100644 --- a/src/jtag/drivers/jtag_vpi.c +++ b/src/jtag/drivers/jtag_vpi.c @@ -627,13 +627,18 @@ static const struct command_registration jtag_vpi_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface jtag_vpi_interface = { - .name = "jtag_vpi", +static struct jtag_interface jtag_vpi_interface = { .supported = DEBUG_CAP_TMS_SEQ, - .commands = jtag_vpi_command_handlers, + .execute_queue = jtag_vpi_execute_queue, +}; + +struct adapter_driver jtag_vpi_adapter_driver = { + .name = "jtag_vpi", .transports = jtag_only, + .commands = jtag_vpi_command_handlers, .init = jtag_vpi_init, .quit = jtag_vpi_quit, - .execute_queue = jtag_vpi_execute_queue, + + .jtag_ops = &jtag_vpi_interface, }; diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index a08f03642..489441111 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -935,12 +935,14 @@ static const struct swd_driver kitprog_swd = { static const char * const kitprog_transports[] = { "swd", NULL }; -struct jtag_interface kitprog_interface = { +struct adapter_driver kitprog_adapter_driver = { .name = "kitprog", - .commands = kitprog_command_handlers, .transports = kitprog_transports, - .swd = &kitprog_swd, + .commands = kitprog_command_handlers, + .init = kitprog_init, .quit = kitprog_quit, .reset = kitprog_reset, + + .swd_ops = &kitprog_swd, }; diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index 5f352af89..539f475bd 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -234,13 +234,19 @@ static const struct command_registration opendous_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface opendous_interface = { +static struct jtag_interface opendous_interface = { + .execute_queue = opendous_execute_queue, +}; + +struct adapter_driver opendous_adapter_driver = { .name = "opendous", .transports = jtag_only, .commands = opendous_command_handlers, - .execute_queue = opendous_execute_queue, + .init = opendous_init, .quit = opendous_quit, + + .jtag_ops = &opendous_interface, }; static int opendous_execute_queue(void) diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 7a3aa2337..24960a8d9 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -892,17 +892,20 @@ static const struct command_registration openjtag_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface openjtag_interface = { +static struct jtag_interface openjtag_interface = { + .execute_queue = openjtag_execute_queue, +}; + +struct adapter_driver openjtag_adapter_driver = { .name = "openjtag", .transports = jtag_only, .commands = openjtag_command_handlers, - .execute_queue = openjtag_execute_queue, - .speed = openjtag_speed, - .speed_div = openjtag_speed_div, - .khz = openjtag_khz, .init = openjtag_init, .quit = openjtag_quit, + .speed = openjtag_speed, + .khz = openjtag_khz, + .speed_div = openjtag_speed_div, + + .jtag_ops = &openjtag_interface, }; - - diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index 5db36a122..ed89a7946 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -688,12 +688,16 @@ static int osbdm_init(void) return ERROR_OK; } -struct jtag_interface osbdm_interface = { - .name = "osbdm", - - .transports = jtag_only, +static struct jtag_interface osbdm_interface = { .execute_queue = osbdm_execute_queue, +}; + +struct adapter_driver osbdm_adapter_driver = { + .name = "osbdm", + .transports = jtag_only, .init = osbdm_init, - .quit = osbdm_quit + .quit = osbdm_quit, + + .jtag_ops = &osbdm_interface, }; diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c index 3a589a3a5..6d15203ae 100644 --- a/src/jtag/drivers/parport.c +++ b/src/jtag/drivers/parport.c @@ -513,17 +513,22 @@ static const struct command_registration parport_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface parport_interface = { - .name = "parport", +static struct jtag_interface parport_interface = { .supported = DEBUG_CAP_TMS_SEQ, + .execute_queue = bitbang_execute_queue, +}; + +struct adapter_driver parport_adapter_driver = { + .name = "parport", .transports = jtag_only, .commands = parport_command_handlers, .init = parport_init, .quit = parport_quit, .reset = parport_reset, + .speed = parport_speed, .khz = parport_khz, .speed_div = parport_speed_div, - .speed = parport_speed, - .execute_queue = bitbang_execute_queue, + + .jtag_ops = &parport_interface, }; diff --git a/src/jtag/drivers/presto.c b/src/jtag/drivers/presto.c index 2a94d0618..3849a27f9 100644 --- a/src/jtag/drivers/presto.c +++ b/src/jtag/drivers/presto.c @@ -561,15 +561,20 @@ static int presto_jtag_quit(void) return ERROR_OK; } -struct jtag_interface presto_interface = { +static struct jtag_interface presto_interface = { + .execute_queue = bitq_execute_queue, +}; + +struct adapter_driver presto_adapter_driver = { .name = "presto", .transports = jtag_only, .commands = presto_command_handlers, - .execute_queue = bitq_execute_queue, + .init = presto_jtag_init, + .quit = presto_jtag_quit, .speed = presto_jtag_speed, .khz = presto_adapter_khz, .speed_div = presto_jtag_speed_div, - .init = presto_jtag_init, - .quit = presto_jtag_quit, + + .jtag_ops = &presto_interface, }; diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c index 70280d23e..663795296 100644 --- a/src/jtag/drivers/remote_bitbang.c +++ b/src/jtag/drivers/remote_bitbang.c @@ -341,12 +341,18 @@ static const struct command_registration remote_bitbang_command_handlers[] = { COMMAND_REGISTRATION_DONE, }; -struct jtag_interface remote_bitbang_interface = { - .name = "remote_bitbang", +static struct jtag_interface remote_bitbang_interface = { .execute_queue = &bitbang_execute_queue, +}; + +struct adapter_driver remote_bitbang_adapter_driver = { + .name = "remote_bitbang", .transports = jtag_only, .commands = remote_bitbang_command_handlers, + .init = &remote_bitbang_init, .quit = &remote_bitbang_quit, .reset = &remote_bitbang_reset, + + .jtag_ops = &remote_bitbang_interface, }; diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c index 317e8b808..e0533997c 100644 --- a/src/jtag/drivers/rlink.c +++ b/src/jtag/drivers/rlink.c @@ -1660,13 +1660,19 @@ static int rlink_quit(void) return ERROR_OK; } -struct jtag_interface rlink_interface = { +static struct jtag_interface rlink_interface = { + .execute_queue = rlink_execute_queue, +}; + +struct adapter_driver rlink_adapter_driver = { .name = "rlink", .transports = jtag_only, + .init = rlink_init, .quit = rlink_quit, .speed = rlink_speed, - .speed_div = rlink_speed_div, .khz = rlink_khz, - .execute_queue = rlink_execute_queue, + .speed_div = rlink_speed_div, + + .jtag_ops = &rlink_interface, }; diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index 706300005..bf33767c8 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -551,16 +551,22 @@ static int sysfsgpio_quit(void); static const char * const sysfsgpio_transports[] = { "jtag", "swd", NULL }; -struct jtag_interface sysfsgpio_interface = { - .name = "sysfsgpio", +static struct jtag_interface sysfsgpio_interface = { .supported = DEBUG_CAP_TMS_SEQ, .execute_queue = bitbang_execute_queue, +}; + +struct adapter_driver sysfsgpio_adapter_driver = { + .name = "sysfsgpio", .transports = sysfsgpio_transports, - .swd = &bitbang_swd, .commands = sysfsgpio_command_handlers, + .init = sysfsgpio_init, .quit = sysfsgpio_quit, .reset = sysfsgpio_reset, + + .jtag_ops = &sysfsgpio_interface, + .swd_ops = &bitbang_swd, }; static struct bitbang_interface sysfsgpio_bitbang = { diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index bbe08aae7..77fbe6193 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -235,7 +235,7 @@ int ulink_queue_stableclocks(struct ulink *device, struct jtag_command *cmd); int ulink_post_process_scan(struct ulink_cmd *ulink_cmd); int ulink_post_process_queue(struct ulink *device); -/* JTAG driver functions (registered in struct jtag_interface) */ +/* adapter driver functions */ static int ulink_execute_queue(void); static int ulink_khz(int khz, int *jtag_speed); static int ulink_speed(int speed); @@ -2272,17 +2272,20 @@ static const struct command_registration ulink_command_handlers[] = { COMMAND_REGISTRATION_DONE, }; -struct jtag_interface ulink_interface = { - .name = "ulink", - - .commands = ulink_command_handlers, - .transports = jtag_only, - +static struct jtag_interface ulink_interface = { .execute_queue = ulink_execute_queue, - .khz = ulink_khz, - .speed = ulink_speed, - .speed_div = ulink_speed_div, +}; + +struct adapter_driver ulink_adapter_driver = { + .name = "ulink", + .transports = jtag_only, + .commands = ulink_command_handlers, .init = ulink_init, - .quit = ulink_quit + .quit = ulink_quit, + .speed = ulink_speed, + .khz = ulink_khz, + .speed_div = ulink_speed_div, + + .jtag_ops = &ulink_interface, }; diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index 48534a26f..fcb594f30 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -1071,13 +1071,18 @@ static const struct command_registration ublast_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface usb_blaster_interface = { +static struct jtag_interface usb_blaster_interface = { + .supported = DEBUG_CAP_TMS_SEQ, + .execute_queue = ublast_execute_queue, +}; + +struct adapter_driver usb_blaster_adapter_driver = { .name = "usb_blaster", .transports = jtag_only, .commands = ublast_command_handlers, - .supported = DEBUG_CAP_TMS_SEQ, - .execute_queue = ublast_execute_queue, .init = ublast_init, .quit = ublast_quit, + + .jtag_ops = &usb_blaster_interface, }; diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c index 35a95202e..6517ce4ad 100644 --- a/src/jtag/drivers/usbprog.c +++ b/src/jtag/drivers/usbprog.c @@ -596,11 +596,16 @@ static void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag) } } -struct jtag_interface usbprog_interface = { +static struct jtag_interface usbprog_interface = { + .execute_queue = usbprog_execute_queue, +}; + +struct adapter_driver usbprog_adapter_driver = { .name = "usbprog", .transports = jtag_only, - .execute_queue = usbprog_execute_queue, .init = usbprog_init, - .quit = usbprog_quit + .quit = usbprog_quit, + + .jtag_ops = &usbprog_interface, }; diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index 5dd1bca40..eb4370233 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -948,18 +948,23 @@ static const struct swd_driver vsllink_swd_driver = { .run = vsllink_swd_run_queue, }; -struct jtag_interface vsllink_interface = { - .name = "vsllink", +static struct jtag_interface vsllink_interface = { .supported = DEBUG_CAP_TMS_SEQ, - .commands = vsllink_command_handlers, + .execute_queue = vsllink_execute_queue, +}; + +struct adapter_driver vsllink_adapter_driver = { + .name = "vsllink", .transports = vsllink_transports, - .swd = &vsllink_swd_driver, + .commands = vsllink_command_handlers, .init = vsllink_init, .quit = vsllink_quit, .reset = vsllink_reset, - .khz = vsllink_khz, .speed = vsllink_speed, + .khz = vsllink_khz, .speed_div = vsllink_speed_div, - .execute_queue = vsllink_execute_queue, + + .jtag_ops = &vsllink_interface, + .swd_ops = &vsllink_swd_driver, }; diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index f0899246b..14bfe9c75 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -2038,17 +2038,22 @@ static const struct swd_driver xds110_swd_driver = { static const char * const xds110_transport[] = { "swd", "jtag", NULL }; -struct jtag_interface xds110_interface = { - .name = "xds110", - .commands = xds110_command_handlers, - .swd = &xds110_swd_driver, - .transports = xds110_transport, - +static struct jtag_interface xds110_interface = { .execute_queue = xds110_execute_queue, - .speed = xds110_speed, - .speed_div = xds110_speed_div, - .khz = xds110_khz, +}; + +struct adapter_driver xds110_adapter_driver = { + .name = "xds110", + .transports = xds110_transport, + .commands = xds110_command_handlers, + .init = xds110_init, .quit = xds110_quit, .reset = xds110_reset, + .speed = xds110_speed, + .khz = xds110_khz, + .speed_div = xds110_speed_div, + + .jtag_ops = &xds110_interface, + .swd_ops = &xds110_swd_driver, }; diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index dbbebed3d..95233c0d7 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -346,10 +346,11 @@ static const struct command_registration hl_interface_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct jtag_interface hl_interface = { +struct adapter_driver hl_adapter_driver = { .name = "hla", - .commands = hl_interface_command_handlers, .transports = hl_transports, + .commands = hl_interface_command_handlers, + .init = hl_interface_init, .quit = hl_interface_quit, .reset = hl_interface_reset, @@ -358,4 +359,6 @@ struct jtag_interface hl_interface = { .speed_div = &hl_interface_speed_div, .config_trace = &hl_interface_config_trace, .poll_trace = &hl_interface_poll_trace, + + /* no ops for HLA, targets hla_target and stm8 intercept them all */ }; diff --git a/src/jtag/interface.h b/src/jtag/interface.h index c5579f5e0..feda35699 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -192,32 +192,34 @@ static inline tap_state_t jtag_debug_state_machine(const void *tms_buf, * debugging interface. */ struct jtag_interface { - /** The name of the JTAG interface driver. */ - const char * const name; - /** * Bit vector listing capabilities exposed by this driver. */ unsigned supported; #define DEBUG_CAP_TMS_SEQ (1 << 0) - /** transports supported in C code (NULL terminated vector) */ - const char * const *transports; - - const struct swd_driver *swd; - /** * Execute queued commands. * @returns ERROR_OK on success, or an error code on failure. */ int (*execute_queue)(void); +}; - /** - * Set the interface speed. - * @param speed The new interface speed setting. - * @returns ERROR_OK on success, or an error code on failure. - */ - int (*speed)(int speed); +/** + * Represents a driver for a debugging interface + * + * @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 adapter_driver { + /** The name of the interface driver. */ + const char * const name; + + /** transports supported in C code (NULL terminated vector) */ + const char * const *transports; /** * The interface driver may register additional commands to expose @@ -260,6 +262,13 @@ struct jtag_interface { */ int (*reset)(int srst, int trst); + /** + * Set the interface speed. + * @param speed The new interface speed setting. + * @returns ERROR_OK on success, or an error code on failure. + */ + int (*speed)(int speed); + /** * Returns JTAG maxium speed for KHz. 0 = RTCK. The function returns * a failure if it can't support the KHz/RTCK. @@ -336,6 +345,12 @@ struct jtag_interface { * @returns ERROR_OK on success, an error code on failure. */ int (*poll_trace)(uint8_t *buf, size_t *size); + + /** Low-level JTAG APIs */ + struct jtag_interface *jtag_ops; + + /** Low-level SWD APIs */ + const struct swd_driver *swd_ops; }; extern const char * const jtag_only[]; diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index 286a73ac6..c35484693 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -34,106 +34,106 @@ /** @file * This file includes declarations for all built-in jtag interfaces, - * which are then listed in the jtag_interfaces array. + * which are then listed in the adapter_drivers array. * * Dynamic loading can be implemented be searching for shared libraries - * that contain a jtag_interface structure that can added to this list. + * that contain an adapter_driver structure that can added to this list. */ #if BUILD_ZY1000 == 1 -extern struct jtag_interface zy1000_interface; +extern struct adapter_driver zy1000_adapter_driver; #elif defined(BUILD_MINIDRIVER_DUMMY) -extern struct jtag_interface minidummy_interface; +extern struct adapter_driver minidummy_adapter_driver; #else /* standard drivers */ #if BUILD_PARPORT == 1 -extern struct jtag_interface parport_interface; +extern struct adapter_driver parport_adapter_driver; #endif #if BUILD_DUMMY == 1 -extern struct jtag_interface dummy_interface; +extern struct adapter_driver dummy_adapter_driver; #endif #if BUILD_FTDI == 1 -extern struct jtag_interface ftdi_interface; +extern struct adapter_driver ftdi_adapter_driver; #endif #if BUILD_USB_BLASTER == 1 || BUILD_USB_BLASTER_2 == 1 -extern struct jtag_interface usb_blaster_interface; +extern struct adapter_driver usb_blaster_adapter_driver; #endif #if BUILD_JTAG_VPI == 1 -extern struct jtag_interface jtag_vpi_interface; +extern struct adapter_driver jtag_vpi_adapter_driver; #endif #if BUILD_FT232R == 1 -extern struct jtag_interface ft232r_interface; +extern struct adapter_driver ft232r_adapter_driver; #endif #if BUILD_AMTJTAGACCEL == 1 -extern struct jtag_interface amt_jtagaccel_interface; +extern struct adapter_driver amt_jtagaccel_adapter_driver; #endif #if BUILD_EP93XX == 1 -extern struct jtag_interface ep93xx_interface; +extern struct adapter_driver ep93xx_adapter_driver; #endif #if BUILD_AT91RM9200 == 1 -extern struct jtag_interface at91rm9200_interface; +extern struct adapter_driver at91rm9200_adapter_driver; #endif #if BUILD_GW16012 == 1 -extern struct jtag_interface gw16012_interface; +extern struct adapter_driver gw16012_adapter_driver; #endif #if BUILD_PRESTO -extern struct jtag_interface presto_interface; +extern struct adapter_driver presto_adapter_driver; #endif #if BUILD_USBPROG == 1 -extern struct jtag_interface usbprog_interface; +extern struct adapter_driver usbprog_adapter_driver; #endif #if BUILD_OPENJTAG == 1 -extern struct jtag_interface openjtag_interface; +extern struct adapter_driver openjtag_adapter_driver; #endif #if BUILD_JLINK == 1 -extern struct jtag_interface jlink_interface; +extern struct adapter_driver jlink_adapter_driver; #endif #if BUILD_VSLLINK == 1 -extern struct jtag_interface vsllink_interface; +extern struct adapter_driver vsllink_adapter_driver; #endif #if BUILD_RLINK == 1 -extern struct jtag_interface rlink_interface; +extern struct adapter_driver rlink_adapter_driver; #endif #if BUILD_ULINK == 1 -extern struct jtag_interface ulink_interface; +extern struct adapter_driver ulink_adapter_driver; #endif #if BUILD_ARMJTAGEW == 1 -extern struct jtag_interface armjtagew_interface; +extern struct adapter_driver armjtagew_adapter_driver; #endif #if BUILD_BUSPIRATE == 1 -extern struct jtag_interface buspirate_interface; +extern struct adapter_driver buspirate_adapter_driver; #endif #if BUILD_REMOTE_BITBANG == 1 -extern struct jtag_interface remote_bitbang_interface; +extern struct adapter_driver remote_bitbang_adapter_driver; #endif #if BUILD_HLADAPTER == 1 -extern struct jtag_interface hl_interface; +extern struct adapter_driver hl_adapter_driver; #endif #if BUILD_OSBDM == 1 -extern struct jtag_interface osbdm_interface; +extern struct adapter_driver osbdm_adapter_driver; #endif #if BUILD_OPENDOUS == 1 -extern struct jtag_interface opendous_interface; +extern struct adapter_driver opendous_adapter_driver; #endif #if BUILD_SYSFSGPIO == 1 -extern struct jtag_interface sysfsgpio_interface; +extern struct adapter_driver sysfsgpio_adapter_driver; #endif #if BUILD_AICE == 1 -extern struct jtag_interface aice_interface; +extern struct adapter_driver aice_adapter_driver; #endif #if BUILD_BCM2835GPIO == 1 -extern struct jtag_interface bcm2835gpio_interface; +extern struct adapter_driver bcm2835gpio_adapter_driver; #endif #if BUILD_CMSIS_DAP == 1 -extern struct jtag_interface cmsis_dap_interface; +extern struct adapter_driver cmsis_dap_adapter_driver; #endif #if BUILD_KITPROG == 1 -extern struct jtag_interface kitprog_interface; +extern struct adapter_driver kitprog_adapter_driver; #endif #if BUILD_IMX_GPIO == 1 -extern struct jtag_interface imx_gpio_interface; +extern struct adapter_driver imx_gpio_adapter_driver; #endif #if BUILD_XDS110 == 1 -extern struct jtag_interface xds110_interface; +extern struct adapter_driver xds110_adapter_driver; #endif #endif /* standard drivers */ @@ -144,107 +144,107 @@ extern struct jtag_interface xds110_interface; * The list should be defined to contain either one minidriver interface * or some number of standard driver interfaces, never both. */ -struct jtag_interface *jtag_interfaces[] = { +struct adapter_driver *adapter_drivers[] = { #if BUILD_ZY1000 == 1 - &zy1000_interface, + &zy1000_adapter_driver, #elif defined(BUILD_MINIDRIVER_DUMMY) - &minidummy_interface, + &minidummy_adapter_driver, #else /* standard drivers */ #if BUILD_PARPORT == 1 - &parport_interface, + &parport_adapter_driver, #endif #if BUILD_DUMMY == 1 - &dummy_interface, + &dummy_adapter_driver, #endif #if BUILD_FTDI == 1 - &ftdi_interface, + &ftdi_adapter_driver, #endif #if BUILD_USB_BLASTER || BUILD_USB_BLASTER_2 == 1 - &usb_blaster_interface, + &usb_blaster_adapter_driver, #endif #if BUILD_JTAG_VPI == 1 - &jtag_vpi_interface, + &jtag_vpi_adapter_driver, #endif #if BUILD_FT232R == 1 - &ft232r_interface, + &ft232r_adapter_driver, #endif #if BUILD_AMTJTAGACCEL == 1 - &amt_jtagaccel_interface, + &amt_jtagaccel_adapter_driver, #endif #if BUILD_EP93XX == 1 - &ep93xx_interface, + &ep93xx_adapter_driver, #endif #if BUILD_AT91RM9200 == 1 - &at91rm9200_interface, + &at91rm9200_adapter_driver, #endif #if BUILD_GW16012 == 1 - &gw16012_interface, + &gw16012_adapter_driver, #endif #if BUILD_PRESTO - &presto_interface, + &presto_adapter_driver, #endif #if BUILD_USBPROG == 1 - &usbprog_interface, + &usbprog_adapter_driver, #endif #if BUILD_OPENJTAG == 1 - &openjtag_interface, + &openjtag_adapter_driver, #endif #if BUILD_JLINK == 1 - &jlink_interface, + &jlink_adapter_driver, #endif #if BUILD_VSLLINK == 1 - &vsllink_interface, + &vsllink_adapter_driver, #endif #if BUILD_RLINK == 1 - &rlink_interface, + &rlink_adapter_driver, #endif #if BUILD_ULINK == 1 - &ulink_interface, + &ulink_adapter_driver, #endif #if BUILD_ARMJTAGEW == 1 - &armjtagew_interface, + &armjtagew_adapter_driver, #endif #if BUILD_BUSPIRATE == 1 - &buspirate_interface, + &buspirate_adapter_driver, #endif #if BUILD_REMOTE_BITBANG == 1 - &remote_bitbang_interface, + &remote_bitbang_adapter_driver, #endif #if BUILD_HLADAPTER == 1 - &hl_interface, + &hl_adapter_driver, #endif #if BUILD_OSBDM == 1 - &osbdm_interface, + &osbdm_adapter_driver, #endif #if BUILD_OPENDOUS == 1 - &opendous_interface, + &opendous_adapter_driver, #endif #if BUILD_SYSFSGPIO == 1 - &sysfsgpio_interface, + &sysfsgpio_adapter_driver, #endif #if BUILD_AICE == 1 - &aice_interface, + &aice_adapter_driver, #endif #if BUILD_BCM2835GPIO == 1 - &bcm2835gpio_interface, + &bcm2835gpio_adapter_driver, #endif #if BUILD_CMSIS_DAP == 1 - &cmsis_dap_interface, + &cmsis_dap_adapter_driver, #endif #if BUILD_KITPROG == 1 - &kitprog_interface, + &kitprog_adapter_driver, #endif #if BUILD_IMX_GPIO == 1 - &imx_gpio_interface, + &imx_gpio_adapter_driver, #endif #if BUILD_XDS110 == 1 - &xds110_interface, + &xds110_adapter_driver, #endif #endif /* standard drivers */ NULL, }; -void jtag_interface_modules_load(const char *path) +void adapter_driver_modules_load(const char *path) { - /* @todo: implement dynamic module loading for JTAG interface drivers */ + /* @todo: implement dynamic module loading for adapter drivers */ } diff --git a/src/jtag/interfaces.h b/src/jtag/interfaces.h index 02d201b1f..f85865a24 100644 --- a/src/jtag/interfaces.h +++ b/src/jtag/interfaces.h @@ -36,9 +36,9 @@ #include -/** Dynamically load all JTAG interface modules from specified directory. */ -void jtag_interface_modules_load(const char *path); +/** Dynamically load all adapter driver modules from specified directory. */ +void adapter_driver_modules_load(const char *path); -extern struct jtag_interface *jtag_interfaces[]; +extern struct adapter_driver *adapter_drivers[]; #endif /* OPENOCD_JTAG_INTERFACES_H */ diff --git a/src/jtag/minidummy/minidummy.c b/src/jtag/minidummy/minidummy.c index 2f260040d..1fce317f0 100644 --- a/src/jtag/minidummy/minidummy.c +++ b/src/jtag/minidummy/minidummy.c @@ -24,18 +24,24 @@ #include #include -struct jtag_interface minidummy_interface = { - .name = "minidummy", +static struct jtag_interface minidummy_interface = { .execute_queue = NULL, - .speed = NULL, +}; + +struct adapter_driver minidummy_adapter_driver = { + .name = "minidummy", .transports = jtag_only, .commands = NULL, + .init = NULL, .quit = NULL, + .speed = NULL, .khz = NULL, .speed_div = NULL, .power_dropout = NULL, .srst_asserted = NULL, + + .jtag_ops = &minidummy_interface, }; int interface_jtag_execute_queue(void) diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index 173498398..48a3d4d03 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -1237,17 +1237,23 @@ int zy1000_init(void) return ERROR_OK; } -struct jtag_interface zy1000_interface = { - .name = "ZY1000", +static struct jtag_interface zy1000_interface = { .supported = DEBUG_CAP_TMS_SEQ, .execute_queue = NULL, - .speed = zy1000_speed, +}; + +struct adapter_driver zy1000_adapter_driver = { + .name = "ZY1000", .transports = jtag_only, .commands = zy1000_commands, + .init = zy1000_init, .quit = zy1000_quit, + .speed = zy1000_speed, .khz = zy1000_khz, .speed_div = zy1000_speed_div, .power_dropout = zy1000_power_dropout, .srst_asserted = zy1000_srst_asserted, + + .jtag_ops = &zy1000_interface, }; diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index 68a50b189..8d1153733 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -368,9 +368,9 @@ static const struct command_registration swd_handlers[] = { static int swd_select(struct command_context *ctx) { - /* FIXME: only place where global 'jtag_interface' is still needed */ - extern struct jtag_interface *jtag_interface; - const struct swd_driver *swd = jtag_interface->swd; + /* FIXME: only place where global 'adapter_driver' is still needed */ + extern struct adapter_driver *adapter_driver; + const struct swd_driver *swd = adapter_driver->swd_ops; int retval; retval = register_commands(ctx, NULL, swd_handlers); diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index 0f2957804..4be94b41b 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -34,7 +34,7 @@ static LIST_HEAD(all_dap); extern const struct dap_ops swd_dap_ops; extern const struct dap_ops jtag_dp_ops; -extern struct jtag_interface *jtag_interface; +extern struct adapter_driver *adapter_driver; /* DAP command support */ struct arm_dap_object { @@ -118,7 +118,7 @@ static int dap_init_all(void) if (transport_is_swd()) { dap->ops = &swd_dap_ops; - obj->swd = jtag_interface->swd; + obj->swd = adapter_driver->swd_ops; } else dap->ops = &jtag_dp_ops; From c6b6fdeb2c4c644addf7b2e1d8c5f0b800d359b7 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 22 Jan 2019 18:23:38 +0100 Subject: [PATCH 073/354] TODO: add restructuring of JTAG/adapter layer SWD is already implemented, so remove the item. Rename the section JTAG as Adapter, including the subsections. Add an initial list of pending activities after the restructure of the JTAG layer. Change-Id: I540777344c62a746df8347538fe8b29e4d72e1c7 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4901 Tested-by: jenkins Reviewed-by: Tomas Vanek --- TODO | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/TODO b/TODO index 350aaa274..a4102eb3b 100644 --- a/TODO +++ b/TODO @@ -37,11 +37,34 @@ This section provides possible things to improve with OpenOCD's TCL support. - See src/jtag/core.c and src/jtag/tcl.c for an example. - allow some of these TCL command modules to be dynamically loadable? -@section thelistjtag JTAG +@section thelistadapter Adapter -This section list issues that need to be resolved in the JTAG layer. +This section list issues that need to be resolved in the Adapter layer. -@subsection thelistjtagcore JTAG Core +@subsection thelistadapterrework Code restructuring + +This section lists pending reworks to complete the restructure from the +old JTAG centric implementation to a generic Adapter layer. +This restructuring is very invasive and will prevent the merge of several +changes pending in gerrit. + +- rename folder src/jtag/ to src/adapter/ +- rename var "jtag" to "adapter" in src/jtag/core.c +- split content of src/adapter/ in the different protocols jtag.[ch], + swd.[ch], ... +- wrap the calls to adapter->transport_ops->api() with transport_api() + and reduce the visibility of global var "adapter" +- complete the migration of JTAG-only drivers to adapter->reset() +- try to remove JTAG_SLEEP also from JTAG mode? +- tap_set_state(TAP_RESET) is already done in src/jtag/core.c. No need + to replicate it in the drivers, apart in case the driver sets TRST + independently +- separate SWIM from HLA and make it independent +- add .hla_ops and .swim_ops to "adapter" +- HLA is a API level (.hla_ops). Transport should simply be {jtag,swd}, + not {hla_jtag,hla_swd}. + +@subsection thelistadapterjtagcore JTAG Core The following tasks have been suggested for cleaning up the JTAG layer: @@ -63,9 +86,9 @@ The following tasks have been suggested for adding new core JTAG support: - (ab)use bit-banging JTAG interfaces to emulate SPI/UART - allow SPI to program flash, MCUs, etc. -@subsection thelistjtaginterfaces JTAG Interfaces +@subsection thelistadapterinterfaces Interface drivers -There are some known bugs to fix in JTAG adapter drivers: +There are some known bugs to fix in Interface drivers: - For JTAG_STATEMOVE to TAP_RESET, all drivers must ignore the current recorded state. The tap_get_state() call won't necessarily return @@ -107,10 +130,6 @@ of a minidriver is required to capture all the jtag_add_xxx() fn's at a high enough level and repackage these cmd's as TCP/IP packets handled by the server. -@section thelistswd Serial Wire Debug - -- implement Serial Wire Debug interface - @section thelistbs Boundary Scan Support - add STAPL support? From a61ec3c1d73dc0c9915662f7b9383b6f786a5fea Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 23 Jan 2019 10:52:28 +0100 Subject: [PATCH 074/354] adi_v5_dapdirect: add support for adapter drivers that provide DAP API Some high level adapters, like STLINK-V3 and new firmware for ST-Link/V2, provide API to directly access the DAP registers hiding the details of the physical transport JTAG or SWD. OpenOCD has already the intermediate API in struct dap_ops that are suitable for such adapters, but are not exposed to the adapter drivers. Add in struct adapter_driver two independent struct dap_ops for the cases of physical JTAG and SWD transport. Add new transport names "dapdirect_jtag" and "dapdirect_swd", to be used by the drivers that provide one or both DAP API. Add the necessarily glue in target/adi_v5_dapdirect.c Change-Id: I2bb8e3a80fba750f2c218d877cfa5888428e3c28 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4903 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/core.c | 6 +- src/jtag/interface.h | 6 + src/target/Makefile.am | 1 + src/target/adi_v5_dapdirect.c | 223 ++++++++++++++++++++++++++++++++++ src/target/arm_dap.c | 4 + src/transport/transport.h | 2 + 6 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 src/target/adi_v5_dapdirect.c diff --git a/src/jtag/core.c b/src/jtag/core.c index 6239573d1..111b122d9 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -2052,7 +2052,8 @@ int adapter_assert_reset(void) else jtag_add_reset(0, 1); return ERROR_OK; - } else if (transport_is_swd() || transport_is_hla()) + } else if (transport_is_swd() || transport_is_hla() || + transport_is_dapdirect_jtag() || transport_is_dapdirect_swd()) return adapter_system_reset(1); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", @@ -2067,7 +2068,8 @@ int adapter_deassert_reset(void) if (transport_is_jtag()) { jtag_add_reset(0, 0); return ERROR_OK; - } else if (transport_is_swd() || transport_is_hla()) + } else if (transport_is_swd() || transport_is_hla() || + transport_is_dapdirect_jtag() || transport_is_dapdirect_swd()) return adapter_system_reset(0); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", diff --git a/src/jtag/interface.h b/src/jtag/interface.h index feda35699..f4c6a98ba 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -351,6 +351,12 @@ struct adapter_driver { /** Low-level SWD APIs */ const struct swd_driver *swd_ops; + + /* DAP APIs over JTAG transport */ + const struct dap_ops *dap_jtag_ops; + + /* DAP APIs over SWD transport */ + const struct dap_ops *dap_swd_ops; }; extern const char * const jtag_only[]; diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 08a4b961f..5a16def55 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -98,6 +98,7 @@ ARM_DEBUG_SRC = \ %D%/arm_dap.c \ %D%/armv7a_cache.c \ %D%/armv7a_cache_l2x.c \ + %D%/adi_v5_dapdirect.c \ %D%/adi_v5_jtag.c \ %D%/adi_v5_swd.c \ %D%/embeddedice.c \ diff --git a/src/target/adi_v5_dapdirect.c b/src/target/adi_v5_dapdirect.c new file mode 100644 index 000000000..f12015198 --- /dev/null +++ b/src/target/adi_v5_dapdirect.c @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2019, STMicroelectronics - All Rights Reserved + * Author(s): Antonio Borneo for STMicroelectronics + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Utilities to support in-circuit debuggers that provide APIs to access + * directly ARM DAP, hiding the access to the underlining transport used + * for the physical connection (either JTAG or SWD). + * E.g. STMicroelectronics ST-Link/V2 (from version V2J24) and STLINK-V3. + * + * Single-DAP support only. + * + * For details, see "ARM IHI 0031A" + * ARM Debug Interface v5 Architecture Specification + * + * FIXME: in JTAG mode, trst is not managed + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +COMMAND_HANDLER(dapdirect_jtag_empty_command) +{ + LOG_DEBUG("dapdirect_jtag_empty_command(\"%s\")", CMD_NAME); + + return ERROR_OK; +} + +COMMAND_HANDLER(dapdirect_jtag_reset_command) +{ + enum reset_types jtag_reset_config = jtag_get_reset_config(); + + /* + * in case the adapter has not already handled asserting srst + * we will attempt it again + */ + if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { + if (jtag_reset_config & RESET_SRST_NO_GATING) { + adapter_assert_reset(); + return ERROR_OK; + } + LOG_WARNING("\'srst_nogate\' reset_config option is required"); + } + adapter_deassert_reset(); + return ERROR_OK; +} + +static const struct command_registration dapdirect_jtag_subcommand_handlers[] = { + { + .name = "newtap", + .mode = COMMAND_CONFIG, + .jim_handler = jim_jtag_newtap, + .help = "declare a new TAP" + }, + { + .name = "init", + .mode = COMMAND_ANY, + .handler = dapdirect_jtag_empty_command, + .usage = "" + }, + { + .name = "arp_init", + .mode = COMMAND_ANY, + .handler = dapdirect_jtag_empty_command, + .usage = "" + }, + { + .name = "arp_init-reset", + .mode = COMMAND_ANY, + .handler = dapdirect_jtag_reset_command, + .usage = "" + }, + { + .name = "tapisenabled", + .mode = COMMAND_EXEC, + .jim_handler = jim_jtag_tap_enabler, + }, + { + .name = "tapenable", + .mode = COMMAND_EXEC, + .jim_handler = jim_jtag_tap_enabler, + }, + { + .name = "tapdisable", + .mode = COMMAND_EXEC, + .handler = dapdirect_jtag_empty_command, + .usage = "", + }, + { + .name = "configure", + .mode = COMMAND_ANY, + .handler = dapdirect_jtag_empty_command, + .usage = "", + }, + { + .name = "cget", + .mode = COMMAND_EXEC, + .jim_handler = jim_jtag_configure, + }, + { + .name = "names", + .mode = COMMAND_ANY, + .handler = dapdirect_jtag_empty_command, + .usage = "", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration dapdirect_jtag_handlers[] = { + { + .name = "jtag", + .mode = COMMAND_ANY, + .chain = dapdirect_jtag_subcommand_handlers, + .usage = "", + }, + { + .name = "jtag_ntrst_delay", + .mode = COMMAND_ANY, + .handler = dapdirect_jtag_empty_command, + .usage = "", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration dapdirect_swd_subcommand_handlers[] = { + { + .name = "newdap", + .mode = COMMAND_CONFIG, + .jim_handler = jim_jtag_newtap, + .help = "declare a new SWD DAP", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration dapdirect_swd_handlers[] = { + { + .name = "swd", + .mode = COMMAND_ANY, + .help = "SWD command group", + .usage = "", + .chain = dapdirect_swd_subcommand_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + +static int dapdirect_jtag_select(struct command_context *ctx) +{ + LOG_DEBUG("dapdirect_jtag_select()"); + + return register_commands(ctx, NULL, dapdirect_jtag_handlers); +} + +static int dapdirect_swd_select(struct command_context *ctx) +{ + LOG_DEBUG("dapdirect_swd_select()"); + + return register_commands(ctx, NULL, dapdirect_swd_handlers); +} + +static int dapdirect_init(struct command_context *ctx) +{ + LOG_DEBUG("dapdirect_init()"); + + adapter_deassert_reset(); + return ERROR_OK; +} + +static struct transport dapdirect_jtag_transport = { + .name = "dapdirect_jtag", + .select = dapdirect_jtag_select, + .init = dapdirect_init, +}; + +static struct transport dapdirect_swd_transport = { + .name = "dapdirect_swd", + .select = dapdirect_swd_select, + .init = dapdirect_init, +}; + +static void dapdirect_constructor(void) __attribute__((constructor)); +static void dapdirect_constructor(void) +{ + transport_register(&dapdirect_jtag_transport); + transport_register(&dapdirect_swd_transport); +} + +/** + * Returns true if the current debug session + * is using JTAG as its transport. + */ +bool transport_is_dapdirect_jtag(void) +{ + return get_current_transport() == &dapdirect_jtag_transport; +} + +/** + * Returns true if the current debug session + * is using SWD as its transport. + */ +bool transport_is_dapdirect_swd(void) +{ + return get_current_transport() == &dapdirect_swd_transport; +} diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index 4be94b41b..56442f183 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -119,6 +119,10 @@ static int dap_init_all(void) if (transport_is_swd()) { dap->ops = &swd_dap_ops; obj->swd = adapter_driver->swd_ops; + } else if (transport_is_dapdirect_swd()) { + dap->ops = adapter_driver->dap_swd_ops; + } else if (transport_is_dapdirect_jtag()) { + dap->ops = adapter_driver->dap_jtag_ops; } else dap->ops = &jtag_dp_ops; diff --git a/src/transport/transport.h b/src/transport/transport.h index 140ef503d..4effca5d5 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -96,6 +96,8 @@ bool transports_are_declared(void); bool transport_is_jtag(void); bool transport_is_swd(void); +bool transport_is_dapdirect_jtag(void); +bool transport_is_dapdirect_swd(void); #if BUILD_HLADAPTER bool transport_is_hla(void); From 944d3e6771bd34e6495276a154929c2c0baf5e0a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 28 Jan 2019 18:53:53 +0100 Subject: [PATCH 075/354] stlink: add DAP direct driver STLINK-V3 and the new firmware V2J24 for ST-LINK/V2 provide API to directly access the DAP registers. This mode permits to use the native target in cortex_m.c, with no need to override it with the target in hla_target.c. Other advantages wrt HLA are: support for Cortex-A cores, support for SoC multi-core and/or multi AP, support for OpenOCD commands "dap" thus including control of CSW. This obsoletes the existing HLA driver for ST-Link, that should anyway be kept for those cases where it's not possible to update the ST-Link firmware. This commit introduces the minimal implementation for direct DAP access. The implementation is much slower than the HLA because every memory transfer requires several USB packets. Further commits will close the performance gap. The whole ST-Link driver is compiled under BUILD_HLADAPTER, to remove the need to split the driver between the two modes. This has to be reworked, but it's quite invasive! A new interface file stlink-dap.cfg is added and should be used in place of stlink.cfg to enable the DAP mode. Documentation is updated and reports limitation on the maximum AP number that can be accessed by ST-Link for some firmware already tested. Change-Id: I932ffe16bc81d00b1fe489e2944fda13470cce9b Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4904 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 37 +- src/jtag/drivers/stlink_usb.c | 653 +++++++++++++++++++++++++++++++++- src/jtag/interfaces.c | 6 + src/target/arm_adi_v5.h | 6 + tcl/interface/stlink-dap.cfg | 17 + 5 files changed, 706 insertions(+), 13 deletions(-) create mode 100644 tcl/interface/stlink-dap.cfg diff --git a/doc/openocd.texi b/doc/openocd.texi index 5da0f806b..b79325276 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3096,6 +3096,29 @@ passed as is to the underlying adapter layout handler. @end deffn @end deffn +@anchor{st_link_dap_interface} +@deffn {Interface Driver} {st-link} +This is a driver that supports STMicroelectronics adapters ST-LINK/V2 +(from firmware V2J24) and STLINK-V3, thanks to a new API that provides +directly access the arm ADIv5 DAP. + +The new API provide access to multiple AP on the same DAP, but the +maximum number of the AP port is limited by the specific firmware version +(e.g. firmware V2J29 has 3 as maximum AP number, while V2J32 has 8). +An error is returned for any AP number above the maximum allowed value. + +@emph{Note:} Either these same adapters and their older versions are +also supported by @ref{hla_interface, the hla interface driver}. + +@deffn {Config Command} {st-link serial} serial +Specifies the serial number of the adapter. +@end deffn + +@deffn {Config Command} {st-link vid_pid} [vid pid]+ +Pairs of vendor IDs and product IDs of the device. +@end deffn +@end deffn + @deffn {Interface Driver} {opendous} opendous-jtag is a freely programmable USB adapter. @end deffn @@ -3204,9 +3227,10 @@ JTAG supports both debugging and boundary scan testing. Flash programming support is built on top of debug support. JTAG transport is selected with the command @command{transport select -jtag}. Unless your adapter uses @ref{hla_interface,the hla interface -driver}, in which case the command is @command{transport select -hla_jtag}. +jtag}. Unless your adapter uses either @ref{hla_interface,the hla interface +driver} (in which case the command is @command{transport select hla_jtag}) +or @ref{st_link_dap_interface,the st-link interface driver} (in which case +the command is @command{transport select dapdirect_jtag}). @subsection SWD Transport @cindex SWD @@ -3219,9 +3243,10 @@ Flash programming support is built on top of debug support. (Some processors support both JTAG and SWD.) SWD transport is selected with the command @command{transport select -swd}. Unless your adapter uses @ref{hla_interface,the hla interface -driver}, in which case the command is @command{transport select -hla_swd}. +swd}. Unless your adapter uses either @ref{hla_interface,the hla interface +driver} (in which case the command is @command{transport select hla_swd}) +or @ref{st_link_dap_interface,the st-link interface driver} (in which case +the command is @command{transport select dapdirect_swd}). @deffn Command {swd newdap} ... Declares a single DAP which uses SWD transport. diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index a16810413..e121eb42b 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -31,11 +31,13 @@ /* project specific includes */ #include +#include #include #include #include #include #include +#include #include @@ -265,10 +267,14 @@ struct stlink_usb_handle_s { #define STLINK_DEBUG_APIV2_GET_TRACE_NB 0x42 #define STLINK_DEBUG_APIV2_SWD_SET_FREQ 0x43 #define STLINK_DEBUG_APIV2_JTAG_SET_FREQ 0x44 - +#define STLINK_DEBUG_APIV2_READ_DAP_REG 0x45 +#define STLINK_DEBUG_APIV2_WRITE_DAP_REG 0x46 #define STLINK_DEBUG_APIV2_READMEM_16BIT 0x47 #define STLINK_DEBUG_APIV2_WRITEMEM_16BIT 0x48 +#define STLINK_DEBUG_APIV2_INIT_AP 0x4B +#define STLINK_DEBUG_APIV2_CLOSE_AP_DBG 0x4C + #define STLINK_APIV3_SET_COM_FREQ 0x61 #define STLINK_APIV3_GET_COM_FREQ 0x62 @@ -278,6 +284,8 @@ struct stlink_usb_handle_s { #define STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH 0x01 #define STLINK_DEBUG_APIV2_DRIVE_NRST_PULSE 0x02 +#define STLINK_DEBUG_PORT_ACCESS 0xffff + #define STLINK_TRACE_SIZE 4096 #define STLINK_TRACE_MAX_HZ 2000000 @@ -300,11 +308,14 @@ enum stlink_mode { * Map the relevant features, quirks and workaround for specific firmware * version of stlink */ -#define STLINK_F_HAS_TRACE (1UL << 0) -#define STLINK_F_HAS_SWD_SET_FREQ (1UL << 1) -#define STLINK_F_HAS_JTAG_SET_FREQ (1UL << 2) -#define STLINK_F_HAS_MEM_16BIT (1UL << 3) -#define STLINK_F_HAS_GETLASTRWSTATUS2 (1UL << 4) +#define STLINK_F_HAS_TRACE BIT(0) +#define STLINK_F_HAS_SWD_SET_FREQ BIT(1) +#define STLINK_F_HAS_JTAG_SET_FREQ BIT(2) +#define STLINK_F_HAS_MEM_16BIT BIT(3) +#define STLINK_F_HAS_GETLASTRWSTATUS2 BIT(4) +#define STLINK_F_HAS_DAP_REG BIT(5) +#define STLINK_F_QUIRK_JTAG_DP_READ BIT(6) +#define STLINK_F_HAS_AP_INIT BIT(7) /* aliases */ #define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE @@ -992,13 +1003,24 @@ static int stlink_usb_version(void *handle) flags |= STLINK_F_HAS_SWD_SET_FREQ; /* API to set JTAG frequency from J24 */ - if (h->version.jtag >= 24) + /* API to access DAP registers from J24 */ + if (h->version.jtag >= 24) { flags |= STLINK_F_HAS_JTAG_SET_FREQ; + flags |= STLINK_F_HAS_DAP_REG; + } + + /* Quirk for read DP in JTAG mode (V2 only) from J24, fixed in J32 */ + if (h->version.jtag >= 24 && h->version.jtag < 32) + flags |= STLINK_F_QUIRK_JTAG_DP_READ; /* API to read/write memory at 16 bit from J26 */ if (h->version.jtag >= 26) flags |= STLINK_F_HAS_MEM_16BIT; + /* API required to init AP before any AP access from J28 */ + if (h->version.jtag >= 28) + flags |= STLINK_F_HAS_AP_INIT; + break; case 3: /* all STLINK-V3 use api-v3 */ @@ -1013,9 +1035,15 @@ static int stlink_usb_version(void *handle) /* preferred API to get last R/W status */ flags |= STLINK_F_HAS_GETLASTRWSTATUS2; + /* API to access DAP registers */ + flags |= STLINK_F_HAS_DAP_REG; + /* API to read/write memory at 16 bit */ flags |= STLINK_F_HAS_MEM_16BIT; + /* API required to init AP before any AP access */ + flags |= STLINK_F_HAS_AP_INIT; + break; default: break; @@ -2930,6 +2958,89 @@ int stlink_config_trace(void *handle, bool enabled, return stlink_usb_trace_enable(h); } +/** */ +static int stlink_usb_init_access_port(void *handle, unsigned char ap_num) +{ + struct stlink_usb_handle_s *h = handle; + + assert(handle != NULL); + + if (!(h->version.flags & STLINK_F_HAS_AP_INIT)) + return ERROR_COMMAND_NOTFOUND; + + LOG_DEBUG_IO("init ap_num = %d", ap_num); + stlink_usb_init_buffer(handle, h->rx_ep, 16); + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_INIT_AP; + h->cmdbuf[h->cmdidx++] = ap_num; + + return stlink_usb_xfer_errcheck(handle, h->databuf, 2); +} + +/** */ +static int stlink_usb_close_access_port(void *handle, unsigned char ap_num) +{ + struct stlink_usb_handle_s *h = handle; + + assert(handle != NULL); + + if (!(h->version.flags & STLINK_F_HAS_AP_INIT)) + return ERROR_COMMAND_NOTFOUND; + + LOG_DEBUG_IO("close ap_num = %d", ap_num); + stlink_usb_init_buffer(handle, h->rx_ep, 16); + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_CLOSE_AP_DBG; + h->cmdbuf[h->cmdidx++] = ap_num; + + return stlink_usb_xfer_errcheck(handle, h->databuf, 2); +} + +/** */ +static int stlink_read_dap_register(void *handle, unsigned short dap_port, + unsigned short addr, uint32_t *val) +{ + struct stlink_usb_handle_s *h = handle; + int retval; + + assert(handle != NULL); + + if (!(h->version.flags & STLINK_F_HAS_DAP_REG)) + return ERROR_COMMAND_NOTFOUND; + + stlink_usb_init_buffer(handle, h->rx_ep, 16); + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READ_DAP_REG; + h_u16_to_le(&h->cmdbuf[2], dap_port); + h_u16_to_le(&h->cmdbuf[4], addr); + + retval = stlink_usb_xfer_errcheck(handle, h->databuf, 8); + *val = le_to_h_u32(h->databuf + 4); + LOG_DEBUG_IO("dap_port_read = %d, addr = 0x%x, value = 0x%x", dap_port, addr, *val); + return retval; +} + +/** */ +static int stlink_write_dap_register(void *handle, unsigned short dap_port, + unsigned short addr, uint32_t val) +{ + struct stlink_usb_handle_s *h = handle; + + assert(handle != NULL); + + if (!(h->version.flags & STLINK_F_HAS_DAP_REG)) + return ERROR_COMMAND_NOTFOUND; + + LOG_DEBUG_IO("dap_write port = %d, addr = 0x%x, value = 0x%x", dap_port, addr, val); + stlink_usb_init_buffer(handle, h->rx_ep, 16); + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; + h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_WRITE_DAP_REG; + h_u16_to_le(&h->cmdbuf[2], dap_port); + h_u16_to_le(&h->cmdbuf[4], addr); + h_u32_to_le(&h->cmdbuf[6], val); + return stlink_usb_xfer_errcheck(handle, h->databuf, 2); +} + /** */ struct hl_layout_api_s stlink_usb_layout_api = { /** */ @@ -2971,3 +3082,531 @@ struct hl_layout_api_s stlink_usb_layout_api = { /** */ .poll_trace = stlink_usb_trace_read, }; + +/***************************************************************************** + * DAP direct interface + */ + +static struct stlink_usb_handle_s *stlink_dap_handle; +static struct hl_interface_param_s stlink_dap_param; +static DECLARE_BITMAP(opened_ap, DP_APSEL_MAX + 1); +static int stlink_dap_error = ERROR_OK; + +static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg, + uint32_t *data); + +/** */ +static int stlink_dap_record_error(int error) +{ + if (stlink_dap_error == ERROR_OK) + stlink_dap_error = error; + return ERROR_OK; +} + +/** */ +static int stlink_dap_get_and_clear_error(void) +{ + int retval = stlink_dap_error; + stlink_dap_error = ERROR_OK; + return retval; +} + +/** */ +static int stlink_dap_open_ap(unsigned short apsel) +{ + int retval; + + /* nothing to do on old versions */ + if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_AP_INIT)) + return ERROR_OK; + + if (apsel > DP_APSEL_MAX) + return ERROR_FAIL; + + if (test_bit(apsel, opened_ap)) + return ERROR_OK; + + retval = stlink_usb_init_access_port(stlink_dap_handle, apsel); + if (retval != ERROR_OK) + return retval; + + LOG_DEBUG("AP %d enabled", apsel); + set_bit(apsel, opened_ap); + return ERROR_OK; +} + +/** */ +static int stlink_dap_closeall_ap(void) +{ + int retval, apsel; + + /* nothing to do on old versions */ + if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_AP_INIT)) + return ERROR_OK; + + for (apsel = 0; apsel <= DP_APSEL_MAX; apsel++) { + if (!test_bit(apsel, opened_ap)) + continue; + retval = stlink_usb_close_access_port(stlink_dap_handle, apsel); + if (retval != ERROR_OK) + return retval; + clear_bit(apsel, opened_ap); + } + return ERROR_OK; +} + +/** */ +static int stlink_dap_reinit_interface(void) +{ + int retval; + enum stlink_mode mode; + + /* + * On JTAG only, it should be enough to call stlink_usb_reset(). But on + * some firmware version it does not work as expected, and there is no + * equivalent for SWD. + * At least for now, to reset the interface quit from JTAG/SWD mode then + * select the mode again. + */ + + mode = stlink_get_mode(stlink_dap_param.transport); + if (!stlink_dap_handle->reconnect_pending) { + stlink_dap_handle->reconnect_pending = true; + stlink_usb_mode_leave(stlink_dap_handle, mode); + } + + retval = stlink_usb_mode_enter(stlink_dap_handle, mode); + if (retval != ERROR_OK) + return retval; + + stlink_dap_handle->reconnect_pending = false; + /* on new FW, calling mode-leave closes all the opened AP; reopen them! */ + if (stlink_dap_handle->version.flags & STLINK_F_HAS_AP_INIT) + for (int apsel = 0; apsel <= DP_APSEL_MAX; apsel++) + if (test_bit(apsel, opened_ap)) { + clear_bit(apsel, opened_ap); + stlink_dap_open_ap(apsel); + } + return ERROR_OK; +} + +/** */ +static int stlink_dap_op_connect(struct adiv5_dap *dap) +{ + uint32_t idcode; + int retval; + + LOG_INFO("stlink_dap_op_connect(%sconnect)", dap->do_reconnect ? "re" : ""); + + /* Check if we should reset srst already when connecting, but not if reconnecting. */ + if (!dap->do_reconnect) { + enum reset_types jtag_reset_config = jtag_get_reset_config(); + + if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { + if (jtag_reset_config & RESET_SRST_NO_GATING) + adapter_assert_reset(); + else + LOG_WARNING("\'srst_nogate\' reset_config option is required"); + } + } + + dap->do_reconnect = false; + dap_invalidate_cache(dap); + + retval = dap_dp_init(dap); + if (retval != ERROR_OK) { + dap->do_reconnect = true; + return retval; + } + + retval = stlink_usb_idcode(stlink_dap_handle, &idcode); + if (retval == ERROR_OK) + LOG_INFO("%s %#8.8" PRIx32, + (stlink_dap_handle->transport == HL_TRANSPORT_JTAG) ? "JTAG IDCODE" : "SWD DPIDR", + idcode); + else + dap->do_reconnect = true; + + return retval; +} + +/** */ +static int stlink_dap_check_reconnect(struct adiv5_dap *dap) +{ + int retval; + + if (!dap->do_reconnect) + return ERROR_OK; + + retval = stlink_dap_reinit_interface(); + if (retval != ERROR_OK) + return retval; + + return stlink_dap_op_connect(dap); +} + +/** */ +static int stlink_dap_op_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq) +{ + /* Ignore the request */ + return ERROR_OK; +} + +/** */ +static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg, + uint32_t *data) +{ + uint32_t dummy; + int retval; + + retval = stlink_dap_check_reconnect(dap); + if (retval != ERROR_OK) + return retval; + + data = data ? : &dummy; + if (stlink_dap_handle->version.flags & STLINK_F_QUIRK_JTAG_DP_READ + && stlink_dap_handle->transport == HL_TRANSPORT_JTAG) { + /* Quirk required in JTAG. Read RDBUFF to get the data */ + retval = stlink_read_dap_register(stlink_dap_handle, + STLINK_DEBUG_PORT_ACCESS, reg, &dummy); + if (retval == ERROR_OK) + retval = stlink_read_dap_register(stlink_dap_handle, + STLINK_DEBUG_PORT_ACCESS, DP_RDBUFF, data); + } else { + retval = stlink_read_dap_register(stlink_dap_handle, + STLINK_DEBUG_PORT_ACCESS, reg, data); + } + + return stlink_dap_record_error(retval); +} + +/** */ +static int stlink_dap_op_queue_dp_write(struct adiv5_dap *dap, unsigned reg, + uint32_t data) +{ + int retval; + + retval = stlink_dap_check_reconnect(dap); + if (retval != ERROR_OK) + return retval; + + /* ST-Link does not like that we set CORUNDETECT */ + if (reg == DP_CTRL_STAT) + data &= ~CORUNDETECT; + + retval = stlink_write_dap_register(stlink_dap_handle, + STLINK_DEBUG_PORT_ACCESS, reg, data); + return stlink_dap_record_error(retval); +} + +/** */ +static int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned reg, + uint32_t *data) +{ + struct adiv5_dap *dap = ap->dap; + uint32_t dummy; + int retval; + + retval = stlink_dap_check_reconnect(dap); + if (retval != ERROR_OK) + return retval; + + if (reg != AP_REG_IDR) { + retval = stlink_dap_open_ap(ap->ap_num); + if (retval != ERROR_OK) + return retval; + } + data = data ? : &dummy; + retval = stlink_read_dap_register(stlink_dap_handle, ap->ap_num, reg, + data); + dap->stlink_flush_ap_write = false; + return stlink_dap_record_error(retval); +} + +/** */ +static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned reg, + uint32_t data) +{ + struct adiv5_dap *dap = ap->dap; + int retval; + + retval = stlink_dap_check_reconnect(dap); + if (retval != ERROR_OK) + return retval; + + retval = stlink_dap_open_ap(ap->ap_num); + if (retval != ERROR_OK) + return retval; + + retval = stlink_write_dap_register(stlink_dap_handle, ap->ap_num, reg, + data); + dap->stlink_flush_ap_write = true; + return stlink_dap_record_error(retval); +} + +/** */ +static int stlink_dap_op_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack) +{ + LOG_WARNING("stlink_dap_op_queue_ap_abort()"); + return ERROR_OK; +} + +/** */ +static int stlink_dap_op_run(struct adiv5_dap *dap) +{ + uint32_t ctrlstat, pwrmask; + int retval, saved_retval; + + /* Here no LOG_DEBUG. This is called continuously! */ + + /* + * ST-Link returns immediately after a DAP write, without waiting for it + * to complete. + * Run a dummy read to DP_RDBUFF, as suggested in + * http://infocenter.arm.com/help/topic/com.arm.doc.faqs/ka16363.html + */ + if (dap->stlink_flush_ap_write) { + dap->stlink_flush_ap_write = false; + retval = stlink_dap_op_queue_dp_read(dap, DP_RDBUFF, NULL); + if (retval != ERROR_OK) { + dap->do_reconnect = true; + return retval; + } + } + + saved_retval = stlink_dap_get_and_clear_error(); + + retval = stlink_dap_op_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat); + if (retval != ERROR_OK) { + dap->do_reconnect = true; + return retval; + } + retval = stlink_dap_get_and_clear_error(); + if (retval != ERROR_OK) { + LOG_ERROR("Fail reading CTRL/STAT register. Force reconnect"); + dap->do_reconnect = true; + return retval; + } + + if (ctrlstat & SSTICKYERR) { + if (stlink_dap_param.transport == HL_TRANSPORT_JTAG) + retval = stlink_dap_op_queue_dp_write(dap, DP_CTRL_STAT, + ctrlstat & (dap->dp_ctrl_stat | SSTICKYERR)); + else + retval = stlink_dap_op_queue_dp_write(dap, DP_ABORT, STKERRCLR); + if (retval != ERROR_OK) { + dap->do_reconnect = true; + return retval; + } + retval = stlink_dap_get_and_clear_error(); + if (retval != ERROR_OK) { + dap->do_reconnect = true; + return retval; + } + } + + /* check for power lost */ + pwrmask = dap->dp_ctrl_stat & (CDBGPWRUPREQ | CSYSPWRUPREQ); + if ((ctrlstat & pwrmask) != pwrmask) + dap->do_reconnect = true; + + return saved_retval; +} + +/** */ +static void stlink_dap_op_quit(struct adiv5_dap *dap) +{ + int retval; + + retval = stlink_dap_closeall_ap(); + if (retval != ERROR_OK) + LOG_ERROR("Error closing APs"); +} + +/** */ +COMMAND_HANDLER(stlink_dap_serial_command) +{ + LOG_DEBUG("stlink_dap_serial_command"); + + if (CMD_ARGC != 1) { + LOG_ERROR("Expected exactly one argument for \"st-link serial \"."); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + if (stlink_dap_param.serial) { + LOG_WARNING("Command \"st-link serial\" already used. Replacing previous value"); + free((void *)stlink_dap_param.serial); + } + + stlink_dap_param.serial = strdup(CMD_ARGV[0]); + return ERROR_OK; +} + +/** */ +COMMAND_HANDLER(stlink_dap_vid_pid) +{ + unsigned int i, max_usb_ids = HLA_MAX_USB_IDS; + + if (CMD_ARGC > max_usb_ids * 2) { + LOG_WARNING("ignoring extra IDs in vid_pid " + "(maximum is %d pairs)", max_usb_ids); + CMD_ARGC = max_usb_ids * 2; + } + if (CMD_ARGC < 2 || (CMD_ARGC & 1)) { + LOG_WARNING("incomplete vid_pid configuration directive"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + for (i = 0; i < CMD_ARGC; i += 2) { + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], stlink_dap_param.vid[i / 2]); + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], stlink_dap_param.pid[i / 2]); + } + + /* null termination */ + stlink_dap_param.vid[i / 2] = stlink_dap_param.pid[i / 2] = 0; + + return ERROR_OK; +} + +/** */ +static const struct command_registration stlink_dap_subcommand_handlers[] = { + { + .name = "serial", + .handler = stlink_dap_serial_command, + .mode = COMMAND_CONFIG, + .help = "set the serial number of the adapter", + .usage = "", + }, + { + .name = "vid_pid", + .handler = stlink_dap_vid_pid, + .mode = COMMAND_CONFIG, + .help = "USB VID and PID of the adapter", + .usage = "(vid pid)+", + }, + COMMAND_REGISTRATION_DONE +}; + +/** */ +static const struct command_registration stlink_dap_command_handlers[] = { + { + .name = "st-link", + .mode = COMMAND_ANY, + .help = "perform st-link management", + .chain = stlink_dap_subcommand_handlers, + .usage = "", + }, + COMMAND_REGISTRATION_DONE +}; + +/** */ +static int stlink_dap_init(void) +{ + enum reset_types jtag_reset_config = jtag_get_reset_config(); + int retval; + + LOG_DEBUG("stlink_dap_init()"); + + if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { + if (jtag_reset_config & RESET_SRST_NO_GATING) + stlink_dap_param.connect_under_reset = true; + else + LOG_WARNING("\'srst_nogate\' reset_config option is required"); + } + + if (transport_is_dapdirect_swd()) + stlink_dap_param.transport = HL_TRANSPORT_SWD; + else if (transport_is_dapdirect_jtag()) + stlink_dap_param.transport = HL_TRANSPORT_JTAG; + else { + LOG_ERROR("Unsupported transport"); + return ERROR_FAIL; + } + + retval = stlink_usb_open(&stlink_dap_param, (void **)&stlink_dap_handle); + if (retval != ERROR_OK) + return retval; + + if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_DAP_REG)) { + LOG_ERROR("ST-Link version does not support DAP direct transport"); + return ERROR_FAIL; + } + return ERROR_OK; +} + +/** */ +static int stlink_dap_quit(void) +{ + LOG_DEBUG("stlink_dap_quit()"); + + free((void *)stlink_dap_param.serial); + stlink_dap_param.serial = NULL; + + return stlink_usb_close(stlink_dap_handle); +} + +/** */ +static int stlink_dap_reset(int req_trst, int req_srst) +{ + LOG_DEBUG("stlink_dap_reset(%d)", req_srst); + return stlink_usb_assert_srst(stlink_dap_handle, + req_srst ? STLINK_DEBUG_APIV2_DRIVE_NRST_LOW + : STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH); +} + +/** */ +static int stlink_dap_speed(int speed) +{ + if (speed == 0) { + LOG_ERROR("RTCK not supported. Set nonzero adapter_khz."); + return ERROR_JTAG_NOT_IMPLEMENTED; + } + + stlink_dap_param.initial_interface_speed = speed; + stlink_speed(stlink_dap_handle, speed, false); + return ERROR_OK; +} + +/** */ +static int stlink_dap_khz(int khz, int *jtag_speed) +{ + *jtag_speed = khz; + return ERROR_OK; +} + +/** */ +static int stlink_dap_speed_div(int speed, int *khz) +{ + *khz = speed; + return ERROR_OK; +} + +static const struct dap_ops stlink_dap_ops = { + .connect = stlink_dap_op_connect, + .send_sequence = stlink_dap_op_send_sequence, + .queue_dp_read = stlink_dap_op_queue_dp_read, + .queue_dp_write = stlink_dap_op_queue_dp_write, + .queue_ap_read = stlink_dap_op_queue_ap_read, + .queue_ap_write = stlink_dap_op_queue_ap_write, + .queue_ap_abort = stlink_dap_op_queue_ap_abort, + .run = stlink_dap_op_run, + .sync = NULL, /* optional */ + .quit = stlink_dap_op_quit, /* optional */ +}; + +static const char *const stlink_dap_transport[] = { "dapdirect_jtag", "dapdirect_swd", NULL }; + +struct adapter_driver stlink_dap_adapter_driver = { + .name = "st-link", + .transports = stlink_dap_transport, + .commands = stlink_dap_command_handlers, + + .init = stlink_dap_init, + .quit = stlink_dap_quit, + .reset = stlink_dap_reset, + .speed = stlink_dap_speed, + .khz = stlink_dap_khz, + .speed_div = stlink_dap_speed_div, + + .dap_jtag_ops = &stlink_dap_ops, + .dap_swd_ops = &stlink_dap_ops, +}; diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index c35484693..17d45415a 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -135,6 +135,9 @@ extern struct adapter_driver imx_gpio_adapter_driver; #if BUILD_XDS110 == 1 extern struct adapter_driver xds110_adapter_driver; #endif +#if BUILD_HLADAPTER == 1 +extern struct adapter_driver stlink_dap_adapter_driver; +#endif #endif /* standard drivers */ /** @@ -240,6 +243,9 @@ struct adapter_driver *adapter_drivers[] = { #if BUILD_XDS110 == 1 &xds110_adapter_driver, #endif +#if BUILD_HLADAPTER == 1 + &stlink_dap_adapter_driver, +#endif #endif /* standard drivers */ NULL, }; diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 88b7e5c87..17365bddb 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -279,6 +279,12 @@ struct adiv5_dap { * swizzle appropriately. */ bool ti_be_32_quirks; + /** + * STLINK adapter need to know if last AP operation was read or write, and + * in case of write has to flush it with a dummy read from DP_RDBUFF + */ + bool stlink_flush_ap_write; + /** * Signals that an attempt to reestablish communication afresh * should be performed before the next access. diff --git a/tcl/interface/stlink-dap.cfg b/tcl/interface/stlink-dap.cfg new file mode 100644 index 000000000..f889f74ed --- /dev/null +++ b/tcl/interface/stlink-dap.cfg @@ -0,0 +1,17 @@ +# +# STMicroelectronics ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit +# debugger/programmer +# +# This new interface driver creates a ST-Link wrapper for ARM-DAP +# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support this method +# + +interface st-link +st-link vid_pid 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 + +# transport select dapdirect_jtag +# transport select dapdirect_swd + +# Optionally specify the serial number of usb device +# e.g. +# st-link serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" From d2308da6e9adc21acd8428afec770670e57bea25 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 28 Feb 2019 10:28:26 +0100 Subject: [PATCH 076/354] stlink: fix handling of DPv1 and DPv2 banked registers Arm DPv1 and DPv2 support banked registers by setting the bank in field DPBANKSEL of register DP_SELECT. Old ST-Link firmware don't support banked registers and setting a bank other than bank zero on DPv1 or DPv2 cause issues in the firmware because it cannot set back bank zero to read CTRL/STAT. New ST-Link firmware mask away DPBANKSEL bits while writing in DP_SELECT but support banked register using the same packed method used by OpenOCD: #define BANK_REG(bank, reg) (((bank) << 4) | (reg)) Add a new macro STLINK_F_HAS_DPBANKSEL for firmware that support arm DPv1 and DPv2, plus trigger an error if banked registers are requested on old firmware. Prevent changing DPBANKSEL on old firmware. Log a debug message when changing DPBANKSEL will be ignored. Change-Id: Iaa592517831d63f8da2290db54f6b32504e3081b Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/4978 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/drivers/stlink_usb.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index e121eb42b..5c904d4ff 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -316,6 +316,7 @@ enum stlink_mode { #define STLINK_F_HAS_DAP_REG BIT(5) #define STLINK_F_QUIRK_JTAG_DP_READ BIT(6) #define STLINK_F_HAS_AP_INIT BIT(7) +#define STLINK_F_HAS_DPBANKSEL BIT(8) /* aliases */ #define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE @@ -1021,6 +1022,10 @@ static int stlink_usb_version(void *handle) if (h->version.jtag >= 28) flags |= STLINK_F_HAS_AP_INIT; + /* Banked regs (DPv1 & DPv2) support from V2J32 */ + if (h->version.jtag >= 32) + flags |= STLINK_F_HAS_DPBANKSEL; + break; case 3: /* all STLINK-V3 use api-v3 */ @@ -1044,6 +1049,10 @@ static int stlink_usb_version(void *handle) /* API required to init AP before any AP access */ flags |= STLINK_F_HAS_AP_INIT; + /* Banked regs (DPv1 & DPv2) support from V3J2 */ + if (h->version.jtag >= 2) + flags |= STLINK_F_HAS_DPBANKSEL; + break; default: break; @@ -3259,6 +3268,12 @@ static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg, uint32_t dummy; int retval; + if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_DPBANKSEL)) + if (reg & 0x000000F0) { + LOG_ERROR("Banked DP registers not supported in current STLink FW"); + return ERROR_COMMAND_NOTFOUND; + } + retval = stlink_dap_check_reconnect(dap); if (retval != ERROR_OK) return retval; @@ -3286,6 +3301,18 @@ static int stlink_dap_op_queue_dp_write(struct adiv5_dap *dap, unsigned reg, { int retval; + if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_DPBANKSEL)) + if (reg & 0x000000F0) { + LOG_ERROR("Banked DP registers not supported in current STLink FW"); + return ERROR_COMMAND_NOTFOUND; + } + + if (reg == DP_SELECT && (data & DP_SELECT_DPBANK) != 0) { + /* ignored if STLINK_F_HAS_DPBANKSEL, not properly managed otherwise */ + LOG_DEBUG("Ignoring DPBANKSEL while write SELECT"); + data &= ~DP_SELECT_DPBANK; + } + retval = stlink_dap_check_reconnect(dap); if (retval != ERROR_OK) return retval; From ed8fa09cfff93dc29903e33e92d36988a30a9529 Mon Sep 17 00:00:00 2001 From: Christopher Head Date: Thu, 6 Jun 2019 11:40:12 -0700 Subject: [PATCH 077/354] target/target: parse value as proper type The `value` variable is passed into `target_fill_mem` as its second-to-last parameter. That parameter is of type `uint64_t`. It is appropriate to parse the value as that type, since otherwise a target with a 32-bit address space but 64-bit data write capabilities would not be able to exercise those capabilities. Change-Id: Ib336d47d42c27cd2b5ba1206b04e8f740f167dba Signed-off-by: Christopher Head Reviewed-on: http://openocd.zylin.com/5219 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/target/target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/target.c b/src/target/target.c index 2bfbd5700..1ec2ee2ed 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -3338,8 +3338,8 @@ COMMAND_HANDLER(handle_mw_command) target_addr_t address; COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address); - target_addr_t value; - COMMAND_PARSE_ADDRESS(CMD_ARGV[1], value); + uint64_t value; + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], value); unsigned count = 1; if (CMD_ARGC == 3) From cc85ebc5acb03a51aafad2e3d913a3c894d93407 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Sun, 5 Jan 2020 23:19:41 +0100 Subject: [PATCH 078/354] flash/nor/stm32l4x : add structure containers to hold devices' information This rework is inspired from the 'flash/nor/stm32h7x.c' This rework will ease the support of new devices on top of this driver: for example: STM32WB have different flash base and size addresses Notes: - stm32l4_probe modified in order to charge the correct part_info from the defined stm32l4_parts according to the device id - stm32l4_flash_bank.bank2_start is replaced by .part_info->bank1_sectors - STM32_FLASH_BASE is removed , part_info->flash_regs_base will be used instead based on that flash register addresses are changed to offsets, >> stm32l4_get_flash_reg was modified accordingly - stm32l4_read_option and stm32l4_write_option was modified to accept an offset instead of an absolute address, luckily this is the commands' argument by default - stm32l4_mass_erase modifications : - use MER2 only on top of dual bank devices - wait for BUSY bit before starting the mass erase Change-Id: Ib35bfc3cbadc76bbeaaaba9005b82077b9e1e744 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/4932 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Andreas Bolsch --- src/flash/nor/stm32l4x.c | 590 ++++++++++++++++++++++----------------- 1 file changed, 337 insertions(+), 253 deletions(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index f680542c7..6aed7731c 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -1,7 +1,10 @@ /*************************************************************************** * Copyright (C) 2015 by Uwe Bonnes * * bon@elektron.ikp.physik.tu-darmstadt.de * - * + * * + * Copyright (C) 2019 by Tarek Bochkati for STMicroelectronics * + * tarek.bouchkati@gmail.com * + * * * 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 * * the Free Software Foundation; either version 2 of the License, or * @@ -24,6 +27,7 @@ #include #include #include +#include "bits.h" /* STM32L4xxx series for reference. * @@ -60,36 +64,34 @@ #define FLASH_ERASE_TIMEOUT 250 -#define STM32_FLASH_BASE 0x40022000 -#define STM32_FLASH_ACR 0x40022000 -#define STM32_FLASH_KEYR 0x40022008 -#define STM32_FLASH_OPTKEYR 0x4002200c -#define STM32_FLASH_SR 0x40022010 -#define STM32_FLASH_CR 0x40022014 -#define STM32_FLASH_OPTR 0x40022020 -#define STM32_FLASH_WRP1AR 0x4002202c -#define STM32_FLASH_WRP1BR 0x40022030 -#define STM32_FLASH_WRP2AR 0x4002204c -#define STM32_FLASH_WRP2BR 0x40022050 +/* Flash registers offsets */ +#define STM32_FLASH_ACR 0x00 +#define STM32_FLASH_KEYR 0x08 +#define STM32_FLASH_OPTKEYR 0x0c +#define STM32_FLASH_SR 0x10 +#define STM32_FLASH_CR 0x14 +#define STM32_FLASH_OPTR 0x20 +#define STM32_FLASH_WRP1AR 0x2c +#define STM32_FLASH_WRP1BR 0x30 +#define STM32_FLASH_WRP2AR 0x4c +#define STM32_FLASH_WRP2BR 0x50 /* FLASH_CR register bits */ - -#define FLASH_PG (1 << 0) -#define FLASH_PER (1 << 1) -#define FLASH_MER1 (1 << 2) -#define FLASH_PAGE_SHIFT 3 -#define FLASH_CR_BKER (1 << 11) -#define FLASH_MER2 (1 << 15) -#define FLASH_STRT (1 << 16) -#define FLASH_OPTSTRT (1 << 17) -#define FLASH_EOPIE (1 << 24) -#define FLASH_ERRIE (1 << 25) +#define FLASH_PG (1 << 0) +#define FLASH_PER (1 << 1) +#define FLASH_MER1 (1 << 2) +#define FLASH_PAGE_SHIFT 3 +#define FLASH_CR_BKER (1 << 11) +#define FLASH_MER2 (1 << 15) +#define FLASH_STRT (1 << 16) +#define FLASH_OPTSTRT (1 << 17) +#define FLASH_EOPIE (1 << 24) +#define FLASH_ERRIE (1 << 25) #define FLASH_OBLLAUNCH (1 << 27) -#define FLASH_OPTLOCK (1 << 30) -#define FLASH_LOCK (1 << 31) +#define FLASH_OPTLOCK (1 << 30) +#define FLASH_LOCK (1 << 31) /* FLASH_SR register bits */ - #define FLASH_BSY (1 << 16) /* Fast programming not used => related errors not used*/ #define FLASH_PGSERR (1 << 7) /* Programming sequence error */ @@ -99,16 +101,9 @@ #define FLASH_PROGERR (1 << 3) /* Programming error */ #define FLASH_OPERR (1 << 1) /* Operation error */ #define FLASH_EOP (1 << 0) /* End of operation */ - #define FLASH_ERROR (FLASH_PGSERR | FLASH_PGSERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_OPERR) -/* STM32_FLASH_OBR bit definitions (reading) */ - -#define OPT_DBANK_LE_1M (1 << 21) /* dual bank for devices up to 1M flash */ -#define OPT_DBANK_GE_2M (1 << 22) /* dual bank for devices with 2M flash */ - /* register unlock keys */ - #define KEY1 0x45670123 #define KEY2 0xCDEF89AB @@ -123,15 +118,107 @@ /* other registers */ #define DBGMCU_IDCODE 0xE0042000 -#define FLASH_SIZE_REG 0x1FFF75E0 -struct stm32l4_flash_bank { - uint16_t bank2_start; - int probed; + +struct stm32l4_rev { + const uint16_t rev; + const char *str; }; -/* flash bank stm32l4x 0 0 - */ +struct stm32l4_part_info { + uint16_t id; + const char *device_str; + const struct stm32l4_rev *revs; + const size_t num_revs; + const uint16_t max_flash_size_kb; + const bool has_dual_bank; + const uint32_t flash_regs_base; + const uint32_t fsize_addr; +}; + +struct stm32l4_flash_bank { + int probed; + uint32_t idcode; + int bank1_sectors; + bool dual_bank_mode; + int hole_sectors; + const struct stm32l4_part_info *part_info; +}; + +static const struct stm32l4_rev stm32_415_revs[] = { + { 0x1000, "1" }, { 0x1001, "2" }, { 0x1003, "3" }, { 0x1007, "4" } +}; + +static const struct stm32l4_rev stm32_435_revs[] = { + { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" }, +}; + +static const struct stm32l4_rev stm32_461_revs[] = { + { 0x1000, "A" }, { 0x2000, "B" }, +}; + +static const struct stm32l4_rev stm32_462_revs[] = { + { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" }, +}; + +static const struct stm32l4_rev stm32_470_revs[] = { + { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x100F, "W" }, +}; + +static const struct stm32l4_part_info stm32l4_parts[] = { + { + .id = 0x415, + .revs = stm32_415_revs, + .num_revs = ARRAY_SIZE(stm32_415_revs), + .device_str = "STM32L47/L48xx", + .max_flash_size_kb = 1024, + .has_dual_bank = true, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, + { + .id = 0x435, + .revs = stm32_435_revs, + .num_revs = ARRAY_SIZE(stm32_435_revs), + .device_str = "STM32L43/L44xx", + .max_flash_size_kb = 256, + .has_dual_bank = false, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, + { + .id = 0x461, + .revs = stm32_461_revs, + .num_revs = ARRAY_SIZE(stm32_461_revs), + .device_str = "STM32L49/L4Axx", + .max_flash_size_kb = 1024, + .has_dual_bank = true, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, + { + .id = 0x462, + .revs = stm32_462_revs, + .num_revs = ARRAY_SIZE(stm32_462_revs), + .device_str = "STM32L45/L46xx", + .max_flash_size_kb = 512, + .has_dual_bank = false, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, + { + .id = 0x470, + .revs = stm32_470_revs, + .num_revs = ARRAY_SIZE(stm32_470_revs), + .device_str = "STM32L4R/L4Sxx", + .max_flash_size_kb = 2048, + .has_dual_bank = true, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, +}; + +/* flash bank stm32l4x 0 0 */ FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command) { struct stm32l4_flash_bank *stm32l4_info; @@ -149,27 +236,30 @@ FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command) return ERROR_OK; } -static inline int stm32l4_get_flash_reg(struct flash_bank *bank, uint32_t reg) +static inline uint32_t stm32l4_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset) { - return reg; + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + return stm32l4_info->part_info->flash_regs_base + reg_offset; } -static inline int stm32l4_get_flash_status(struct flash_bank *bank, uint32_t *status) +static inline int stm32l4_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value) { - struct target *target = bank->target; - return target_read_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_SR), status); + return target_read_u32(bank->target, stm32l4_get_flash_reg(bank, reg_offset), value); +} + +static inline int stm32l4_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value) +{ + return target_write_u32(bank->target, stm32l4_get_flash_reg(bank, reg_offset), value); } static int stm32l4_wait_status_busy(struct flash_bank *bank, int timeout) { - struct target *target = bank->target; uint32_t status; int retval = ERROR_OK; /* wait for busy to clear */ for (;;) { - retval = stm32l4_get_flash_status(bank, &status); + retval = stm32l4_read_flash_reg(bank, STM32_FLASH_SR, &status); if (retval != ERROR_OK) return retval; LOG_DEBUG("status: 0x%" PRIx32 "", status); @@ -195,20 +285,20 @@ static int stm32l4_wait_status_busy(struct flash_bank *bank, int timeout) /* If this operation fails, we ignore it and report the original * retval */ - target_write_u32(target, stm32l4_get_flash_reg(bank, STM32_FLASH_SR), - status & FLASH_ERROR); + stm32l4_write_flash_reg(bank, STM32_FLASH_SR, status & FLASH_ERROR); } + return retval; } -static int stm32l4_unlock_reg(struct target *target) +static int stm32l4_unlock_reg(struct flash_bank *bank) { uint32_t ctrl; /* first check if not already unlocked * otherwise writing on STM32_FLASH_KEYR will fail */ - int retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); + int retval = stm32l4_read_flash_reg(bank, STM32_FLASH_CR, &ctrl); if (retval != ERROR_OK) return retval; @@ -216,15 +306,15 @@ static int stm32l4_unlock_reg(struct target *target) return ERROR_OK; /* unlock flash registers */ - retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1); + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_KEYR, KEY1); if (retval != ERROR_OK) return retval; - retval = target_write_u32(target, STM32_FLASH_KEYR, KEY2); + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_KEYR, KEY2); if (retval != ERROR_OK) return retval; - retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); + retval = stm32l4_read_flash_reg(bank, STM32_FLASH_CR, &ctrl); if (retval != ERROR_OK) return retval; @@ -236,11 +326,11 @@ static int stm32l4_unlock_reg(struct target *target) return ERROR_OK; } -static int stm32l4_unlock_option_reg(struct target *target) +static int stm32l4_unlock_option_reg(struct flash_bank *bank) { uint32_t ctrl; - int retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); + int retval = stm32l4_read_flash_reg(bank, STM32_FLASH_CR, &ctrl); if (retval != ERROR_OK) return retval; @@ -248,15 +338,15 @@ static int stm32l4_unlock_option_reg(struct target *target) return ERROR_OK; /* unlock option registers */ - retval = target_write_u32(target, STM32_FLASH_OPTKEYR, OPTKEY1); + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_OPTKEYR, OPTKEY1); if (retval != ERROR_OK) return retval; - retval = target_write_u32(target, STM32_FLASH_OPTKEYR, OPTKEY2); + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_OPTKEYR, OPTKEY2); if (retval != ERROR_OK) return retval; - retval = target_read_u32(target, STM32_FLASH_CR, &ctrl); + retval = stm32l4_read_flash_reg(bank, STM32_FLASH_CR, &ctrl); if (retval != ERROR_OK) return retval; @@ -268,36 +358,29 @@ static int stm32l4_unlock_option_reg(struct target *target) return ERROR_OK; } -static int stm32l4_read_option(struct flash_bank *bank, uint32_t address, uint32_t* value) +static int stm32l4_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value, uint32_t mask) { - struct target *target = bank->target; - return target_read_u32(target, address, value); -} - -static int stm32l4_write_option(struct flash_bank *bank, uint32_t address, uint32_t value, uint32_t mask) -{ - struct target *target = bank->target; uint32_t optiondata; - int retval = target_read_u32(target, address, &optiondata); + int retval = stm32l4_read_flash_reg(bank, reg_offset, &optiondata); if (retval != ERROR_OK) return retval; - retval = stm32l4_unlock_reg(target); + retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) return retval; - retval = stm32l4_unlock_option_reg(target); + retval = stm32l4_unlock_option_reg(bank); if (retval != ERROR_OK) return retval; optiondata = (optiondata & ~mask) | (value & mask); - retval = target_write_u32(target, address, optiondata); + retval = stm32l4_write_flash_reg(bank, reg_offset, optiondata); if (retval != ERROR_OK) return retval; - retval = target_write_u32(target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), FLASH_OPTSTRT); + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_OPTSTRT); if (retval != ERROR_OK) return retval; @@ -311,11 +394,12 @@ static int stm32l4_write_option(struct flash_bank *bank, uint32_t address, uint3 static int stm32l4_protect_check(struct flash_bank *bank) { struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + uint32_t wrp1ar, wrp1br, wrp2ar, wrp2br; - stm32l4_read_option(bank, STM32_FLASH_WRP1AR, &wrp1ar); - stm32l4_read_option(bank, STM32_FLASH_WRP1BR, &wrp1br); - stm32l4_read_option(bank, STM32_FLASH_WRP2AR, &wrp2ar); - stm32l4_read_option(bank, STM32_FLASH_WRP2BR, &wrp2br); + stm32l4_read_flash_reg(bank, STM32_FLASH_WRP1AR, &wrp1ar); + stm32l4_read_flash_reg(bank, STM32_FLASH_WRP1BR, &wrp1br); + stm32l4_read_flash_reg(bank, STM32_FLASH_WRP2AR, &wrp2ar); + stm32l4_read_flash_reg(bank, STM32_FLASH_WRP2BR, &wrp2br); const uint8_t wrp1a_start = wrp1ar & 0xFF; const uint8_t wrp1a_end = (wrp1ar >> 16) & 0xFF; @@ -327,7 +411,7 @@ static int stm32l4_protect_check(struct flash_bank *bank) const uint8_t wrp2b_end = (wrp2br >> 16) & 0xFF; for (int i = 0; i < bank->num_sectors; i++) { - if (i < stm32l4_info->bank2_start) { + if (i < stm32l4_info->bank1_sectors) { if (((i >= wrp1a_start) && (i <= wrp1a_end)) || ((i >= wrp1b_start) && @@ -337,7 +421,7 @@ static int stm32l4_protect_check(struct flash_bank *bank) bank->sectors[i].is_protected = 0; } else { uint8_t snb; - snb = i - stm32l4_info->bank2_start; + snb = i - stm32l4_info->bank1_sectors; if (((snb >= wrp2a_start) && (snb <= wrp2a_end)) || ((snb >= wrp2b_start) && @@ -352,8 +436,9 @@ static int stm32l4_protect_check(struct flash_bank *bank) static int stm32l4_erase(struct flash_bank *bank, int first, int last) { - struct target *target = bank->target; + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; int i; + int retval; assert(first < bank->num_sectors); assert(last < bank->num_sectors); @@ -363,8 +448,7 @@ static int stm32l4_erase(struct flash_bank *bank, int first, int last) return ERROR_TARGET_NOT_HALTED; } - int retval; - retval = stm32l4_unlock_reg(target); + retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) return retval; @@ -378,20 +462,18 @@ static int stm32l4_erase(struct flash_bank *bank, int first, int last) 3. Set the STRT bit in the FLASH_CR register 4. Wait for the BSY bit to be cleared */ - struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; for (i = first; i <= last; i++) { uint32_t erase_flags; erase_flags = FLASH_PER | FLASH_STRT; - if (i >= stm32l4_info->bank2_start) { + if (i >= stm32l4_info->bank1_sectors) { uint8_t snb; - snb = i - stm32l4_info->bank2_start; + snb = i - stm32l4_info->bank1_sectors; erase_flags |= snb << FLASH_PAGE_SHIFT | FLASH_CR_BKER; } else erase_flags |= i << FLASH_PAGE_SHIFT; - retval = target_write_u32(target, - stm32l4_get_flash_reg(bank, STM32_FLASH_CR), erase_flags); + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, erase_flags); if (retval != ERROR_OK) return retval; @@ -402,8 +484,7 @@ static int stm32l4_erase(struct flash_bank *bank, int first, int last) bank->sectors[i].is_erased = 1; } - retval = target_write_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK); + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); if (retval != ERROR_OK) return retval; @@ -423,9 +504,9 @@ static int stm32l4_protect(struct flash_bank *bank, int set, int first, int last int ret = ERROR_OK; /* Bank 2 */ uint32_t reg_value = 0xFF; /* Default to bank un-protected */ - if (last >= stm32l4_info->bank2_start) { + if (last >= stm32l4_info->bank1_sectors) { if (set == 1) { - uint8_t begin = first > stm32l4_info->bank2_start ? first : 0x00; + uint8_t begin = first > stm32l4_info->bank1_sectors ? first : 0x00; reg_value = ((last & 0xFF) << 16) | begin; } @@ -433,9 +514,9 @@ static int stm32l4_protect(struct flash_bank *bank, int set, int first, int last } /* Bank 1 */ reg_value = 0xFF; /* Default to bank un-protected */ - if (first < stm32l4_info->bank2_start) { + if (first < stm32l4_info->bank1_sectors) { if (set == 1) { - uint8_t end = last >= stm32l4_info->bank2_start ? 0xFF : last; + uint8_t end = last >= stm32l4_info->bank1_sectors ? 0xFF : last; reg_value = (end << 16) | (first & 0xFF); } @@ -450,6 +531,7 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct target *target = bank->target; + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; uint32_t buffer_size = 16384; struct working_area *write_algorithm; struct working_area *source; @@ -503,7 +585,7 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); buf_set_u32(reg_params[2].value, 0, 32, address); buf_set_u32(reg_params[3].value, 0, 32, count / 4); - buf_set_u32(reg_params[4].value, 0, 32, STM32_FLASH_BASE); + buf_set_u32(reg_params[4].value, 0, 32, stm32l4_info->part_info->flash_regs_base); retval = target_run_flash_async_algorithm(target, buffer, count, 2, 0, NULL, @@ -523,7 +605,7 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, if (error != 0) { LOG_ERROR("flash write failed = %08" PRIx32, error); /* Clear but report errors */ - target_write_u32(target, STM32_FLASH_SR, error); + stm32l4_write_flash_reg(bank, STM32_FLASH_SR, error); retval = ERROR_FAIL; } } @@ -543,7 +625,6 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { - struct target *target = bank->target; int retval; if (bank->target->state != TARGET_HALTED) { @@ -570,7 +651,7 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, */ } - retval = stm32l4_unlock_reg(target); + retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) return retval; @@ -579,60 +660,69 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, if (retval != ERROR_OK) { LOG_WARNING("block write failed"); return retval; - } + } LOG_WARNING("block write succeeded"); - return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK); + return stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); +} + +static int stm32l4_read_idcode(struct flash_bank *bank, uint32_t *id) +{ + int retval = target_read_u32(bank->target, DBGMCU_IDCODE, id); + if (retval != ERROR_OK) + return retval; + + return retval; } static int stm32l4_probe(struct flash_bank *bank) { struct target *target = bank->target; struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + const struct stm32l4_part_info *part_info; int i; uint16_t flash_size_in_kb = 0xffff; - uint16_t max_flash_size_in_kb; uint32_t device_id; uint32_t options; - uint32_t base_address = 0x08000000; stm32l4_info->probed = 0; /* read stm32 device id register */ - int retval = target_read_u32(target, DBGMCU_IDCODE, &device_id); + int retval = stm32l4_read_idcode(bank, &stm32l4_info->idcode); if (retval != ERROR_OK) return retval; - LOG_INFO("device id = 0x%08" PRIx32 "", device_id); - /* set max flash size depending on family */ - switch (device_id & 0xfff) { - case 0x470: - max_flash_size_in_kb = 2048; - break; - case 0x461: - case 0x415: - max_flash_size_in_kb = 1024; - break; - case 0x462: - max_flash_size_in_kb = 512; - break; - case 0x435: - max_flash_size_in_kb = 256; - break; - default: + device_id = stm32l4_info->idcode & 0xFFF; + + for (unsigned int n = 0; n < ARRAY_SIZE(stm32l4_parts); n++) { + if (device_id == stm32l4_parts[n].id) + stm32l4_info->part_info = &stm32l4_parts[n]; + } + + if (!stm32l4_info->part_info) { LOG_WARNING("Cannot identify target as an STM32L4 family device."); return ERROR_FAIL; } + part_info = stm32l4_info->part_info; + + char device_info[1024]; + retval = bank->driver->info(bank, device_info, sizeof(device_info)); + if (retval != ERROR_OK) + return retval; + + LOG_INFO("device idcode = 0x%08" PRIx32 " (%s)", stm32l4_info->idcode, device_info); + /* get flash size from target. */ - retval = target_read_u16(target, FLASH_SIZE_REG, &flash_size_in_kb); + retval = target_read_u16(target, part_info->fsize_addr, &flash_size_in_kb); /* failed reading flash size or flash size invalid (early silicon), * default to max target family */ - if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) { + if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0 + || flash_size_in_kb > part_info->max_flash_size_kb) { LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming %dk flash", - max_flash_size_in_kb); - flash_size_in_kb = max_flash_size_in_kb; + part_info->max_flash_size_kb); + flash_size_in_kb = part_info->max_flash_size_kb; } LOG_INFO("flash size = %dkbytes", flash_size_in_kb); @@ -640,91 +730,106 @@ static int stm32l4_probe(struct flash_bank *bank) /* did we assign a flash size? */ assert((flash_size_in_kb != 0xffff) && flash_size_in_kb); - /* get options for DUAL BANK. */ - retval = target_read_u32(target, STM32_FLASH_OPTR, &options); - + /* read flash option register */ + retval = stm32l4_read_flash_reg(bank, STM32_FLASH_OPTR, &options); if (retval != ERROR_OK) return retval; + stm32l4_info->bank1_sectors = 0; + stm32l4_info->hole_sectors = 0; + int num_pages = 0; int page_size = 0; - switch (device_id & 0xfff) { - case 0x470: - /* L4R/S have 1M or 2M FLASH and dual/single bank mode. - * Page size is 4K or 8K.*/ - if (flash_size_in_kb == 2048) { - stm32l4_info->bank2_start = 256; - if (options & OPT_DBANK_GE_2M) { - page_size = 4096; - num_pages = 512; - } else { - page_size = 8192; - num_pages = 256; - } - break; - } - if (flash_size_in_kb == 1024) { - stm32l4_info->bank2_start = 128; - if (options & OPT_DBANK_LE_1M) { - page_size = 4096; - num_pages = 256; - } else { - page_size = 8192; - num_pages = 128; - } - break; - } - /* Invalid FLASH size for this device. */ - LOG_WARNING("Invalid flash size for STM32L4+ family device."); - return ERROR_FAIL; - case 0x461: - case 0x415: - /* These are dual-bank devices, we need to check the OPT_DBANK_LE_1M bit here */ - page_size = 2048; - num_pages = flash_size_in_kb / 2; - /* check that calculation result makes sense */ - assert(num_pages > 0); - if ((flash_size_in_kb == 1024) || !(options & OPT_DBANK_LE_1M)) - stm32l4_info->bank2_start = 256; - else - stm32l4_info->bank2_start = num_pages / 2; - break; - case 0x462: - case 0x435: - default: - /* These are single-bank devices */ - page_size = 2048; - num_pages = flash_size_in_kb / 2; - /* check that calculation result makes sense */ - assert(num_pages > 0); - stm32l4_info->bank2_start = UINT16_MAX; - break; + stm32l4_info->dual_bank_mode = false; + + switch (device_id) { + case 0x415: + case 0x461: + /* if flash size is max (1M) the device is always dual bank + * 0x415: has variants with 512K + * 0x461: has variants with 512 and 256 + * for these variants: + * if DUAL_BANK = 0 -> single bank + * else -> dual bank without gap + * note: the page size is invariant + */ + page_size = 2048; + num_pages = flash_size_in_kb / 2; + stm32l4_info->bank1_sectors = num_pages; + + /* check DUAL_BANK bit[21] if the flash is less than 1M */ + if (flash_size_in_kb == 1024 || (options & BIT(21))) { + stm32l4_info->dual_bank_mode = true; + stm32l4_info->bank1_sectors = num_pages / 2; + } + break; + case 0x435: + case 0x462: + /* single bank flash */ + page_size = 2048; + num_pages = flash_size_in_kb / 2; + stm32l4_info->bank1_sectors = num_pages; + break; + case 0x470: + /* STM32L4R/S can be single/dual bank: + * if size = 2M check DBANK bit(22) + * if size = 1M check DB1M bit(21) + * in single bank configuration the page size is 8K + * else (dual bank) the page size is 4K without gap between banks + */ + page_size = 8192; + num_pages = flash_size_in_kb / 8; + stm32l4_info->bank1_sectors = num_pages; + if ((flash_size_in_kb == 2048 && (options & BIT(22))) || + (flash_size_in_kb == 1024 && (options & BIT(21)))) { + stm32l4_info->dual_bank_mode = true; + page_size = 4096; + num_pages = flash_size_in_kb / 4; + stm32l4_info->bank1_sectors = num_pages / 2; + } + break; + default: + LOG_ERROR("unsupported device"); + return ERROR_FAIL; + } + + LOG_INFO("flash mode : %s-bank", stm32l4_info->dual_bank_mode ? "dual" : "single"); + + const int gap_size = stm32l4_info->hole_sectors * page_size; + + if (stm32l4_info->dual_bank_mode & gap_size) { + LOG_INFO("gap detected starting from %0x08" PRIx32 " to %0x08" PRIx32, + 0x8000000 + stm32l4_info->bank1_sectors * page_size, + 0x8000000 + stm32l4_info->bank1_sectors * page_size + gap_size); } - /* Release sector table if allocated. */ if (bank->sectors) { free(bank->sectors); bank->sectors = NULL; } - /* Set bank configuration and construct sector table. */ - bank->base = base_address; - bank->size = num_pages * page_size; + bank->size = flash_size_in_kb * 1024 + gap_size; + bank->base = 0x08000000; bank->num_sectors = num_pages; - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); - if (!bank->sectors) - return ERROR_FAIL; /* Checkme: What better error to use?*/ + bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); + if (bank->sectors == NULL) { + LOG_ERROR("failed to allocate bank sectors"); + return ERROR_FAIL; + } - for (i = 0; i < num_pages; i++) { + for (i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = i * page_size; + /* in dual bank configuration, if there is a gap between banks + * we fix up the sector offset to consider this gap */ + if (i >= stm32l4_info->bank1_sectors && stm32l4_info->hole_sectors) + bank->sectors[i].offset += gap_size; bank->sectors[i].size = page_size; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } stm32l4_info->probed = 1; - return ERROR_OK; } @@ -733,87 +838,70 @@ static int stm32l4_auto_probe(struct flash_bank *bank) struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; if (stm32l4_info->probed) return ERROR_OK; + return stm32l4_probe(bank); } static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size) { - struct target *target = bank->target; - uint32_t dbgmcu_idcode; + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + const struct stm32l4_part_info *part_info = stm32l4_info->part_info; - /* read stm32 device id register */ - int retval = target_read_u32(target, DBGMCU_IDCODE, &dbgmcu_idcode); - if (retval != ERROR_OK) - return retval; + if (part_info) { + const char *rev_str = NULL; + uint16_t rev_id = stm32l4_info->idcode >> 16; + for (unsigned int i = 0; i < part_info->num_revs; i++) { + if (rev_id == part_info->revs[i].rev) { + rev_str = part_info->revs[i].str; - uint16_t device_id = dbgmcu_idcode & 0xfff; - uint8_t rev_id = dbgmcu_idcode >> 28; - uint8_t rev_minor = 0; - int i; + if (rev_str != NULL) { + snprintf(buf, buf_size, "%s - Rev: %s", + part_info->device_str, rev_str); + return ERROR_OK; + } + } + } - for (i = 16; i < 28; i++) { - if (dbgmcu_idcode & (1 << i)) - rev_minor++; - else - break; - } - - const char *device_str; - - switch (device_id) { - case 0x470: - device_str = "STM32L4R/4Sxx"; - break; - - case 0x461: - device_str = "STM32L496/4A6"; - break; - - case 0x415: - device_str = "STM32L475/476/486"; - break; - - case 0x462: - device_str = "STM32L45x/46x"; - break; - - case 0x435: - device_str = "STM32L43x/44x"; - break; - - default: - snprintf(buf, buf_size, "Cannot identify target as a STM32L4\n"); + snprintf(buf, buf_size, "%s - Rev: unknown (0x%04x)", + part_info->device_str, rev_id); + return ERROR_OK; + } else { + snprintf(buf, buf_size, "Cannot identify target as a STM32L4x device"); return ERROR_FAIL; } - snprintf(buf, buf_size, "%s - Rev: %1d.%02d", - device_str, rev_id, rev_minor); - return ERROR_OK; } -static int stm32l4_mass_erase(struct flash_bank *bank, uint32_t action) +static int stm32l4_mass_erase(struct flash_bank *bank) { int retval; struct target *target = bank->target; + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + + uint32_t action = FLASH_MER1; + + if (stm32l4_info->part_info->has_dual_bank) + action |= FLASH_MER2; if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } - retval = stm32l4_unlock_reg(target); + retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) return retval; /* mass erase flash memory */ - retval = target_write_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), action); + retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT / 10); if (retval != ERROR_OK) return retval; - retval = target_write_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), - action | FLASH_STRT); + + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, action); + if (retval != ERROR_OK) + return retval; + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, action | FLASH_STRT); if (retval != ERROR_OK) return retval; @@ -821,8 +909,7 @@ static int stm32l4_mass_erase(struct flash_bank *bank, uint32_t action) if (retval != ERROR_OK) return retval; - retval = target_write_u32( - target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK); + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); if (retval != ERROR_OK) return retval; @@ -832,7 +919,6 @@ static int stm32l4_mass_erase(struct flash_bank *bank, uint32_t action) COMMAND_HANDLER(stm32l4_handle_mass_erase_command) { int i; - uint32_t action; if (CMD_ARGC < 1) { command_print(CMD, "stm32l4x mass_erase "); @@ -844,8 +930,7 @@ COMMAND_HANDLER(stm32l4_handle_mass_erase_command) if (ERROR_OK != retval) return retval; - action = FLASH_MER1 | FLASH_MER2; - retval = stm32l4_mass_erase(bank, action); + retval = stm32l4_mass_erase(bank); if (retval == ERROR_OK) { /* set all sectors as erased */ for (i = 0; i < bank->num_sectors; i++) @@ -871,12 +956,13 @@ COMMAND_HANDLER(stm32l4_handle_option_read_command) if (ERROR_OK != retval) return retval; - uint32_t reg_addr = STM32_FLASH_BASE; + uint32_t reg_offset, reg_addr; uint32_t value = 0; - reg_addr += strtoul(CMD_ARGV[1], NULL, 16); + reg_offset = strtoul(CMD_ARGV[1], NULL, 16); + reg_addr = stm32l4_get_flash_reg(bank, reg_offset); - retval = stm32l4_read_option(bank, reg_addr, &value); + retval = stm32l4_read_flash_reg(bank, reg_offset, &value); if (ERROR_OK != retval) return retval; @@ -897,11 +983,11 @@ COMMAND_HANDLER(stm32l4_handle_option_write_command) if (ERROR_OK != retval) return retval; - uint32_t reg_addr = STM32_FLASH_BASE; + uint32_t reg_offset; uint32_t value = 0; uint32_t mask = 0xFFFFFFFF; - reg_addr += strtoul(CMD_ARGV[1], NULL, 16); + reg_offset = strtoul(CMD_ARGV[1], NULL, 16); value = strtoul(CMD_ARGV[2], NULL, 16); if (CMD_ARGC > 3) mask = strtoul(CMD_ARGV[3], NULL, 16); @@ -910,7 +996,7 @@ COMMAND_HANDLER(stm32l4_handle_option_write_command) "INFO: a reset or power cycle is required " "for the new settings to take effect.", bank->driver->name); - retval = stm32l4_write_option(bank, reg_addr, value, mask); + retval = stm32l4_write_option(bank, reg_offset, value, mask); return retval; } @@ -924,18 +1010,16 @@ COMMAND_HANDLER(stm32l4_handle_option_load_command) if (ERROR_OK != retval) return retval; - struct target *target = bank->target; - - retval = stm32l4_unlock_reg(target); + retval = stm32l4_unlock_reg(bank); if (ERROR_OK != retval) return retval; - retval = stm32l4_unlock_option_reg(target); + retval = stm32l4_unlock_option_reg(bank); if (ERROR_OK != retval) return retval; /* Write the OBLLAUNCH bit in CR -> Cause device "POR" and option bytes reload */ - retval = target_write_u32(target, stm32l4_get_flash_reg(bank, STM32_FLASH_CR), FLASH_OBLLAUNCH); + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_OBLLAUNCH); command_print(CMD, "stm32l4x option load (POR) completed."); return retval; From 8536306b6ebcee8249376734d64db40a07916c9d Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 6 Jan 2020 15:47:09 +0100 Subject: [PATCH 079/354] flash/nor: add support of STM32L41/L42xx tested using STM32L412KB Change-Id: I1e2ae93d8c740db219f0fb579940de7f2fffac15 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/4934 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/stm32l4x.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 6aed7731c..9057872ac 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -161,6 +161,10 @@ static const struct stm32l4_rev stm32_462_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" }, }; +static const struct stm32l4_rev stm32_464_revs[] = { + { 0x1000, "A" }, +}; + static const struct stm32l4_rev stm32_470_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x100F, "W" }, }; @@ -206,6 +210,16 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .flash_regs_base = 0x40022000, .fsize_addr = 0x1FFF75E0, }, + { + .id = 0x464, + .revs = stm32_464_revs, + .num_revs = ARRAY_SIZE(stm32_464_revs), + .device_str = "STM32L41/L42xx", + .max_flash_size_kb = 128, + .has_dual_bank = false, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, { .id = 0x470, .revs = stm32_470_revs, @@ -766,6 +780,7 @@ static int stm32l4_probe(struct flash_bank *bank) break; case 0x435: case 0x462: + case 0x464: /* single bank flash */ page_size = 2048; num_pages = flash_size_in_kb / 2; From a6a642bf72a12c9a1fc4b92de2dc46d12cb3b58e Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 6 Jan 2020 17:19:31 +0100 Subject: [PATCH 080/354] flash/nor: add support of STM32WB on top STM32L4 flash driver Change-Id: I9fb6700085d817d35a691f6484193f67939a4e0f Signed-off-by: Laurent LEMELE Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/4933 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 6 ++- src/flash/nor/stm32l4x.c | 24 ++++++++- tcl/target/stm32wbx.cfg | 103 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 tcl/target/stm32wbx.cfg diff --git a/doc/openocd.texi b/doc/openocd.texi index b79325276..c526a632a 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6869,7 +6869,7 @@ The @var{num} parameter is a value shown by @command{flash banks}. @end deffn @deffn {Flash Driver} stm32l4x -All members of the STM32L4 microcontroller families from STMicroelectronics +All members of the STM32L4 and STM32WB microcontroller families from STMicroelectronics include internal flash and use ARM Cortex-M4 cores. The driver automatically recognizes a number of these chips using the chip identification register, and autoconfigures itself. @@ -6911,7 +6911,9 @@ is the register offset of the Option byte to read. For example to read the FLASH_OPTR register: @example stm32l4x option_read 0 0x20 -# Option Register: <0x40022020> = 0xffeff8aa +# Option Register (for STM32L4x): <0x40022020> = 0xffeff8aa +# Option Register (for STM32WBx): <0x58004020> = ... +# The correct flash base address will be used automatically @end example The above example will read out the FLASH_OPTR register which contains the RDP diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 9057872ac..a373f1168 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -169,6 +169,10 @@ static const struct stm32l4_rev stm32_470_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x100F, "W" }, }; +static const struct stm32l4_rev stm32_495_revs[] = { + { 0x2001, "2.1" }, +}; + static const struct stm32l4_part_info stm32l4_parts[] = { { .id = 0x415, @@ -230,6 +234,16 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .flash_regs_base = 0x40022000, .fsize_addr = 0x1FFF75E0, }, + { + .id = 0x495, + .revs = stm32_495_revs, + .num_revs = ARRAY_SIZE(stm32_495_revs), + .device_str = "STM32WB5x", + .max_flash_size_kb = 1024, + .has_dual_bank = false, + .flash_regs_base = 0x58004000, + .fsize_addr = 0x1FFF75E0, + }, }; /* flash bank stm32l4x 0 0 */ @@ -714,7 +728,7 @@ static int stm32l4_probe(struct flash_bank *bank) } if (!stm32l4_info->part_info) { - LOG_WARNING("Cannot identify target as an STM32L4 family device."); + LOG_WARNING("Cannot identify target as an STM32 L4 or WB family device."); return ERROR_FAIL; } @@ -804,6 +818,12 @@ static int stm32l4_probe(struct flash_bank *bank) stm32l4_info->bank1_sectors = num_pages / 2; } break; + case 0x495: + /* single bank flash */ + page_size = 4096; + num_pages = flash_size_in_kb / 4; + stm32l4_info->bank1_sectors = num_pages; + break; default: LOG_ERROR("unsupported device"); return ERROR_FAIL; @@ -881,7 +901,7 @@ static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size) part_info->device_str, rev_id); return ERROR_OK; } else { - snprintf(buf, buf_size, "Cannot identify target as a STM32L4x device"); + snprintf(buf, buf_size, "Cannot identify target as an STM32 L4 or WB device"); return ERROR_FAIL; } diff --git a/tcl/target/stm32wbx.cfg b/tcl/target/stm32wbx.cfg new file mode 100644 index 000000000..138bcf186 --- /dev/null +++ b/tcl/target/stm32wbx.cfg @@ -0,0 +1,103 @@ +# script for stm32wbx family + +# +# stm32wb devices support both JTAG and SWD transports. +# +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32wbx +} + +set _ENDIAN little + +# Work-area is a space in RAM used for flash programming +# By default use 64kB +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x10000 +} + +#jtag scan chain +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + if { [using_jtag] } { + set _CPUTAPID 0x6ba00477 + } else { + # SWD IDCODE (single drop, arm) + set _CPUTAPID 0x6ba02477 + } +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +if {[using_jtag]} { + jtag newtap $_CHIPNAME bs -irlen 5 +} + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME + +# Common knowledges tells JTAG speed should be <= F_CPU/6. +# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on +# the safe side. +# +# Note that there is a pretty wide band where things are +# more or less stable, see http://openocd.zylin.com/#/c/3366/ +adapter_khz 500 + +adapter_nsrst_delay 100 +if {[using_jtag]} { + jtag_ntrst_delay 100 +} + +reset_config srst_nogate + +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +$_TARGETNAME configure -event reset-init { + # CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz. + # Configure system to use MSI 24 MHz clock, compliant with VOS default Range1. + # 2 WS compliant with VOS=Range1 and 24 MHz. + mmw 0x58004000 0x00000102 0 ;# FLASH_ACR |= PRFTBE | 2(Latency) + mmw 0x58000000 0x00000091 0 ;# RCC_CR = MSI_ON | MSI Range 24 MHz + # Boost JTAG frequency + adapter_khz 4000 +} + +$_TARGETNAME configure -event reset-start { + # Reset clock is MSI (4 MHz) + adapter_khz 500 +} + +$_TARGETNAME configure -event examine-end { + # Enable debug during low power modes (uses more power) + # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP + mmw 0xE0042004 0x00000007 0 + + # Stop watchdog counters during halt + # DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP + mmw 0xE004203C 0x00001800 0 +} + +$_TARGETNAME configure -event trace-config { + # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync + # change this value accordingly to configure trace pins + # assignment + mmw 0xE0042004 0x00000020 0 +} From 251eb035fc72c8fe6348fa21d8c8d8faa9902988 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 6 Jan 2020 18:33:42 +0100 Subject: [PATCH 081/354] flash/nor/stm32l4x: add support of STM32L4P5/L4Q5x devices STM32L4P/Q devices have: - similar flash layout as STM32L4R/S devices - 1024K of flash memory (some parts have 512K only) tested on NUCLEO-L4P5ZG using board/st_nucleo_l4.cfg Change-Id: I77047351bc7dcd7c76d0f31a77be73005104a06f Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5392 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/stm32l4x.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index a373f1168..3d1537756 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -51,12 +51,17 @@ * RM0394 devices have a single bank only. * * RM0432 devices have single and dual bank operating modes. - * The FLASH size is 1Mbyte or 2Mbyte. + * - for STM32L4R/Sxx the FLASH size is 2Mbyte or 1Mbyte. + * - for STM32L4P/Q5x the FLASH size is 1Mbyte or 512Kbyte. * Bank page (sector) size is 4Kbyte (dual mode) or 8Kbyte (single mode). * * Bank mode is controlled by two different bits in option bytes register. - * In 2M FLASH devices bit 22 (DBANK) controls Dual Bank mode. - * In 1M FLASH devices bit 21 (DB1M) controls Dual Bank mode. + * - for STM32L4R/Sxx + * In 2M FLASH devices bit 22 (DBANK) controls Dual Bank mode. + * In 1M FLASH devices bit 21 (DB1M) controls Dual Bank mode. + * - for STM32L4P5/Q5x + * In 1M FLASH devices bit 22 (DBANK) controls Dual Bank mode. + * In 512K FLASH devices bit 21 (DB512K) controls Dual Bank mode. * */ @@ -169,6 +174,10 @@ static const struct stm32l4_rev stm32_470_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x100F, "W" }, }; +static const struct stm32l4_rev stm32_471_revs[] = { + { 0x1000, "1" }, +}; + static const struct stm32l4_rev stm32_495_revs[] = { { 0x2001, "2.1" }, }; @@ -234,6 +243,16 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .flash_regs_base = 0x40022000, .fsize_addr = 0x1FFF75E0, }, + { + .id = 0x471, + .revs = stm32_471_revs, + .num_revs = ARRAY_SIZE(stm32_471_revs), + .device_str = "STM32L4P5/L4Q5x", + .max_flash_size_kb = 1024, + .has_dual_bank = true, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, { .id = 0x495, .revs = stm32_495_revs, @@ -801,17 +820,22 @@ static int stm32l4_probe(struct flash_bank *bank) stm32l4_info->bank1_sectors = num_pages; break; case 0x470: + case 0x471: /* STM32L4R/S can be single/dual bank: * if size = 2M check DBANK bit(22) * if size = 1M check DB1M bit(21) + * STM32L4P/Q can be single/dual bank + * if size = 1M check DBANK bit(22) + * if size = 512K check DB512K bit(21) * in single bank configuration the page size is 8K * else (dual bank) the page size is 4K without gap between banks */ page_size = 8192; num_pages = flash_size_in_kb / 8; stm32l4_info->bank1_sectors = num_pages; - if ((flash_size_in_kb == 2048 && (options & BIT(22))) || - (flash_size_in_kb == 1024 && (options & BIT(21)))) { + const bool use_dbank_bit = flash_size_in_kb == part_info->max_flash_size_kb; + if ((use_dbank_bit && (options & BIT(22))) || + (!use_dbank_bit && (options & BIT(21)))) { stm32l4_info->dual_bank_mode = true; page_size = 4096; num_pages = flash_size_in_kb / 4; From 35d9bf9917fc9c00a6b8e941a5479e85878ef33c Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:38:42 +0100 Subject: [PATCH 082/354] xsvf: fix memory leak Discovered by clang static analyzer. Change-Id: I2980586aea5ee43226adb1f4cf72e7ba1dfddd83 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5372 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/xsvf/xsvf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c index e574c6f0e..bec32f21e 100644 --- a/src/xsvf/xsvf.c +++ b/src/xsvf/xsvf.c @@ -918,8 +918,10 @@ COMMAND_HANDLER(handle_xsvf_command) struct scan_field field; result = svf_add_statemove(loop_state); - if (result != ERROR_OK) + if (result != ERROR_OK) { + free(dr_in_mask); return result; + } jtag_add_clocks(loop_clocks); jtag_add_sleep(loop_usecs); From 98a8b99ef37542dc34e1b247d9946a127d4ab70d Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:40:07 +0100 Subject: [PATCH 083/354] server/server: fix clang static analyzer warning Change-Id: I317e189b62540e3688a20d88a95f551280317f14 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5373 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/server/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/server.c b/src/server/server.c index 9e63f74f4..8e641176a 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -562,7 +562,7 @@ int server_loop(struct command_context *command_context) struct connection *c; for (c = service->connections; c; ) { - if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending) { + if ((c->fd >= 0 && FD_ISSET(c->fd, &read_fds)) || c->input_pending) { retval = service->input(c); if (retval != ERROR_OK) { struct connection *next = c->next; From 5dd5cf26bd18ddaacbdbded881cfbefacda71631 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:43:55 +0100 Subject: [PATCH 084/354] target/arm946e: add missing error detection Discoverd by clang static analyzer. While on it remove useless type casts from arm946e_read_cp15() parameter. Change-Id: I549e19685b431400243800ee0f7d1bbe6cdb14b4 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5376 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/arm946e.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/target/arm946e.c b/src/target/arm946e.c index 112631a7c..4ef167a9d 100644 --- a/src/target/arm946e.c +++ b/src/target/arm946e.c @@ -267,7 +267,11 @@ uint32_t arm946e_invalidate_whole_dcache(struct target *target) /* Read dtag */ uint32_t dtag; - arm946e_read_cp15(target, 0x16, (uint32_t *) &dtag); + retval = arm946e_read_cp15(target, 0x16, &dtag); + if (retval != ERROR_OK) { + LOG_DEBUG("ERROR reading dtag"); + return retval; + } /* Check cache line VALID bit */ if (!(dtag >> 4 & 0x1)) @@ -321,7 +325,7 @@ int arm946e_post_debug_entry(struct target *target) /* See if CACHES are enabled, and save that info * in the context bits, so that arm946e_pre_restore_context() can use them */ - arm946e_read_cp15(target, CP15_CTL, (uint32_t *) &ctr_reg); + arm946e_read_cp15(target, CP15_CTL, &ctr_reg); /* Save control reg in the context */ arm946e->cp15_control_reg = ctr_reg; @@ -362,7 +366,7 @@ void arm946e_pre_restore_context(struct target *target) if (arm946e_preserve_cache) { struct arm946e_common *arm946e = target_to_arm946(target); /* Get the contents of the CTR reg */ - arm946e_read_cp15(target, CP15_CTL, (uint32_t *) &ctr_reg); + arm946e_read_cp15(target, CP15_CTL, &ctr_reg); /** * Read-modify-write CP15 control @@ -410,7 +414,11 @@ uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address, } /* Read dtag */ - arm946e_read_cp15(target, 0x16, (uint32_t *) &dtag); + retval = arm946e_read_cp15(target, 0x16, &dtag); + if (retval != ERROR_OK) { + LOG_DEBUG("ERROR reading dtag"); + return retval; + } /* Check cache line VALID bit */ if (!(dtag >> 4 & 0x1)) @@ -463,7 +471,11 @@ uint32_t arm946e_invalidate_icache(struct target *target, uint32_t address, } /* Read itag */ - arm946e_read_cp15(target, 0x17, (uint32_t *) &itag); + retval = arm946e_read_cp15(target, 0x17, &itag); + if (retval != ERROR_OK) { + LOG_DEBUG("ERROR reading itag"); + return retval; + } /* Check cache line VALID bit */ if (!(itag >> 4 & 0x1)) From 8bb1998e6afe8488c44828e69b5b0d5092f39545 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:45:20 +0100 Subject: [PATCH 085/354] target/arm_dpm: add missing error returns Discoverd by clang static analyzer. Change-Id: I93d5de0a36216e62b170fe8cc870431226a7777f Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5377 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/arm_dpm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index 8b9957033..f5dd22d8b 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -145,6 +145,9 @@ static int dpm_read_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum) retval = dpm->instr_read_data_r0(dpm, ARMV4_5_VMOV(1, 1, 0, ((regnum - ARM_VFP_V3_D0) >> 4), ((regnum - ARM_VFP_V3_D0) & 0xf)), &value_r0); + if (retval != ERROR_OK) + break; + /* read r1 via dcc */ retval = dpm->instr_read_data_dcc(dpm, ARMV4_5_MCR(14, 0, 1, 0, 5, 0), @@ -248,6 +251,9 @@ static int dpm_write_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum retval = dpm->instr_write_data_dcc(dpm, ARMV4_5_MRC(14, 0, 1, 0, 5, 0), value_r1); + if (retval != ERROR_OK) + break; + /* write value_r0 to r0 via dcc then, * move to double word register from r0:r1: "vmov vm, r0, r1" */ From b04d9c05f0eadc7161465755c05a1f3c1bd6a85b Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:46:46 +0100 Subject: [PATCH 086/354] target/avr32_jtag: fix error returns Fixed only 2 error returns discovered by clang static analyzer. There are obviously many more missing error tests in avr32_jtag.c These was not fixed to keep this change minimal. Not tested with hw. Change-Id: I6c79f6248db774990ddb42c0dacdb621651ed69e Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5378 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/avr32_jtag.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/target/avr32_jtag.c b/src/target/avr32_jtag.c index 6526810e2..c17fbe7f0 100644 --- a/src/target/avr32_jtag.c +++ b/src/target/avr32_jtag.c @@ -173,19 +173,15 @@ int avr32_jtag_nexus_read(struct avr32_jtag *jtag_info, { avr32_jtag_set_instr(jtag_info, AVR32_INST_NEXUS_ACCESS); avr32_jtag_nexus_set_address(jtag_info, addr, MODE_READ); - avr32_jtag_nexus_read_data(jtag_info, value); - - return ERROR_OK; - + return avr32_jtag_nexus_read_data(jtag_info, value); } + int avr32_jtag_nexus_write(struct avr32_jtag *jtag_info, uint32_t addr, uint32_t value) { avr32_jtag_set_instr(jtag_info, AVR32_INST_NEXUS_ACCESS); avr32_jtag_nexus_set_address(jtag_info, addr, MODE_WRITE); - avr32_jtag_nexus_write_data(jtag_info, value); - - return ERROR_OK; + return avr32_jtag_nexus_write_data(jtag_info, value); } int avr32_jtag_mwa_set_address(struct avr32_jtag *jtag_info, int slave, From 57afa176ce858ad6505a9a962df5d7e978d349bf Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:48:13 +0100 Subject: [PATCH 087/354] target/target: fix clang static analyzer warnings Change-Id: I23e6586be60915f21a7179a994a1ec93fb9b2c36 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5379 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/target.c b/src/target/target.c index 1ec2ee2ed..936a5da0d 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1682,7 +1682,7 @@ static int target_call_timer_callbacks_check_time(int checktime) * next item; initially, that's a standalone "root of the * list" variable. */ struct target_timer_callback **callback = &target_timer_callbacks; - while (*callback) { + while (callback && *callback) { if ((*callback)->removed) { struct target_timer_callback *p = *callback; *callback = (*callback)->next; From fe6bb7eac8c7028236306c562d24a25ef79d0c15 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:48:46 +0100 Subject: [PATCH 088/354] target/semihosting_common: fix minor memory leak Reported by clang static analyzer. Change-Id: Ie663f49d92588c0d8b502cfdd8fc34004b308066 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5380 Reviewed-by: Liviu Ionescu Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/semihosting_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index ce6a79171..a41f8e4c8 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -944,6 +944,8 @@ int semihosting_common(struct target *target) uint8_t *fn1 = malloc(len1+1); uint8_t *fn2 = malloc(len2+1); if (!fn1 || !fn2) { + free(fn1); + free(fn2); semihosting->result = -1; semihosting->sys_errno = ENOMEM; } else { From af0dda82666e1e4f241fabc0db62212d51413a08 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:50:26 +0100 Subject: [PATCH 089/354] target/etm: add check for calloc error and fix one more clang static analyzer warning. Change-Id: I17f03e318e1cf7617e7f753e7ca960552be547e5 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5381 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/etm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/target/etm.c b/src/target/etm.c index 5751348e7..d1cfe61f6 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -303,6 +303,11 @@ struct reg_cache *etm_build_reg_cache(struct target *target, reg_list = calloc(128, sizeof(struct reg)); arch_info = calloc(128, sizeof(struct etm_reg)); + if (reg_cache == NULL || reg_list == NULL || arch_info == NULL) { + LOG_ERROR("No memory"); + goto fail; + } + /* fill in values for the reg cache */ reg_cache->name = "etm registers"; reg_cache->next = NULL; @@ -498,6 +503,7 @@ static int etm_read_reg_w_check(struct reg *reg, uint8_t *check_value, uint8_t *check_mask) { struct etm_reg *etm_reg = reg->arch_info; + assert(etm_reg); const struct etm_reg_info *r = etm_reg->reg_info; uint8_t reg_addr = r->addr & 0x7f; struct scan_field fields[3]; From 7fffa3cbc6f85480eaf1498d30c45af5933bd017 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:54:29 +0100 Subject: [PATCH 090/354] target/xscale: remove duplicated command Reported by clang static analyzer. Change-Id: I893af10852af4885507ed62d024008159a80dd56 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5382 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/xscale.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/target/xscale.c b/src/target/xscale.c index 1a099c946..3ef8922b5 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -3227,7 +3227,6 @@ COMMAND_HANDLER(xscale_handle_vector_catch_command) if (retval != ERROR_OK) return retval; - dcsr_value = buf_get_u32(dcsr_reg->value, 0, 32); if (CMD_ARGC > 0) { if (CMD_ARGC == 1) { if (strcmp(CMD_ARGV[0], "all") == 0) { From f83ce0a2ef7fa9c844d4591e4586911c14c44ac8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 21 Apr 2019 16:28:10 +0200 Subject: [PATCH 091/354] flash/nor: Pass flash_bank to memory accessors Replace passing in struct target with passing in struct flash_bank, so that the later can contain function pointers to custom per-driver memory accessor functions. Change-Id: Id2573a6d5f1a73ed9c4f73c53592a9a335a11c99 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5146 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/cfi.c | 54 ++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index c22bcdecb..3e265dd39 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -131,18 +131,18 @@ static inline uint32_t flash_address(struct flash_bank *bank, int sector, uint32 } } -static int cfi_target_write_memory(struct target *target, target_addr_t addr, +static int cfi_target_write_memory(struct flash_bank *bank, target_addr_t addr, uint32_t size, uint32_t count, const uint8_t *buffer) { - return target_write_memory(target, addr, size, count, buffer); + return target_write_memory(bank->target, addr, size, count, buffer); } -static int cfi_target_read_memory(struct target *target, target_addr_t addr, +static int cfi_target_read_memory(struct flash_bank *bank, target_addr_t addr, uint32_t size, uint32_t count, uint8_t *buffer) { - return target_read_memory(target, addr, size, count, buffer); + return target_read_memory(bank->target, addr, size, count, buffer); } static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf) @@ -170,7 +170,7 @@ static int cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t addre uint8_t command[CFI_MAX_BUS_WIDTH]; cfi_command(bank, cmd, command); - return cfi_target_write_memory(bank->target, address, bank->bus_width, 1, command); + return cfi_target_write_memory(bank, address, bank->bus_width, 1, command); } /* read unsigned 8-bit value from the bank @@ -179,12 +179,11 @@ static int cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t addre */ static int cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset, uint8_t *val) { - struct target *target = bank->target; struct cfi_flash_bank *cfi_info = bank->driver_priv; uint8_t data[CFI_MAX_BUS_WIDTH]; int retval; - retval = cfi_target_read_memory(target, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), bank->bus_width, 1, data); if (retval != ERROR_OK) return retval; @@ -203,13 +202,12 @@ static int cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset, ui */ static int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint8_t *val) { - struct target *target = bank->target; struct cfi_flash_bank *cfi_info = bank->driver_priv; uint8_t data[CFI_MAX_BUS_WIDTH]; int i; int retval; - retval = cfi_target_read_memory(target, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), bank->bus_width, 1, data); if (retval != ERROR_OK) return retval; @@ -231,7 +229,6 @@ static int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint static int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, uint16_t *val) { - struct target *target = bank->target; struct cfi_flash_bank *cfi_info = bank->driver_priv; uint8_t data[CFI_MAX_BUS_WIDTH * 2]; int retval; @@ -239,13 +236,13 @@ static int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, u if (cfi_info->x16_as_x8) { uint8_t i; for (i = 0; i < 2; i++) { - retval = cfi_target_read_memory(target, flash_address(bank, sector, offset + i), + retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset + i), bank->bus_width, 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) return retval; } } else { - retval = cfi_target_read_memory(target, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), bank->bus_width, 2, data); if (retval != ERROR_OK) return retval; @@ -261,7 +258,6 @@ static int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, u static int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, uint32_t *val) { - struct target *target = bank->target; struct cfi_flash_bank *cfi_info = bank->driver_priv; uint8_t data[CFI_MAX_BUS_WIDTH * 4]; int retval; @@ -269,13 +265,13 @@ static int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, u if (cfi_info->x16_as_x8) { uint8_t i; for (i = 0; i < 4; i++) { - retval = cfi_target_read_memory(target, flash_address(bank, sector, offset + i), + retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset + i), bank->bus_width, 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) return retval; } } else { - retval = cfi_target_read_memory(target, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), bank->bus_width, 4, data); if (retval != ERROR_OK) return retval; @@ -2004,14 +2000,13 @@ static int cfi_intel_write_word(struct flash_bank *bank, uint8_t *word, uint32_t { int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; cfi_intel_clear_status_register(bank); retval = cfi_send_command(bank, 0x40, address); if (retval != ERROR_OK) return retval; - retval = cfi_target_write_memory(target, address, bank->bus_width, 1, word); + retval = cfi_target_write_memory(bank, address, bank->bus_width, 1, word); if (retval != ERROR_OK) return retval; @@ -2038,7 +2033,6 @@ static int cfi_intel_write_words(struct flash_bank *bank, const uint8_t *word, { int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; /* Calculate buffer size and boundary mask * buffersize is (buffer size per chip) * (number of chips) @@ -2092,7 +2086,7 @@ static int cfi_intel_write_words(struct flash_bank *bank, const uint8_t *word, if (retval != ERROR_OK) return retval; - retval = cfi_target_write_memory(target, address, bank->bus_width, bufferwsize, word); + retval = cfi_target_write_memory(bank, address, bank->bus_width, bufferwsize, word); if (retval != ERROR_OK) return retval; @@ -2123,7 +2117,6 @@ static int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint3 int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - struct target *target = bank->target; retval = cfi_spansion_unlock_seq(bank); if (retval != ERROR_OK) @@ -2133,7 +2126,7 @@ static int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint3 if (retval != ERROR_OK) return retval; - retval = cfi_target_write_memory(target, address, bank->bus_width, 1, word); + retval = cfi_target_write_memory(bank, address, bank->bus_width, 1, word); if (retval != ERROR_OK) return retval; @@ -2155,7 +2148,6 @@ static int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word { int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; /* Calculate buffer size and boundary mask * buffersize is (buffer size per chip) * (number of chips) @@ -2195,7 +2187,7 @@ static int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word if (retval != ERROR_OK) return retval; - retval = cfi_target_write_memory(target, address, bank->bus_width, bufferwsize, word); + retval = cfi_target_write_memory(bank, address, bank->bus_width, bufferwsize, word); if (retval != ERROR_OK) return retval; @@ -2268,7 +2260,6 @@ static int cfi_write_words(struct flash_bank *bank, const uint8_t *word, static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; uint32_t address = bank->base + offset; uint32_t read_p; int align; /* number of unaligned bytes */ @@ -2297,7 +2288,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u LOG_INFO("Fixup %d unaligned read head bytes", align); /* read a complete word from flash */ - retval = cfi_target_read_memory(target, read_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(bank, read_p, bank->bus_width, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2310,7 +2301,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u align = count / bank->bus_width; if (align) { - retval = cfi_target_read_memory(target, read_p, bank->bus_width, align, buffer); + retval = cfi_target_read_memory(bank, read_p, bank->bus_width, align, buffer); if (retval != ERROR_OK) return retval; @@ -2323,7 +2314,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u LOG_INFO("Fixup %" PRIu32 " unaligned read tail bytes", count); /* read a complete word from flash */ - retval = cfi_target_read_memory(target, read_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(bank, read_p, bank->bus_width, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2338,7 +2329,6 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct target *target = bank->target; uint32_t address = bank->base + offset; /* address of first byte to be programmed */ uint32_t write_p; int align; /* number of unaligned bytes */ @@ -2368,7 +2358,7 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of LOG_INFO("Fixup %d unaligned head bytes", align); /* read a complete word from flash */ - retval = cfi_target_read_memory(target, write_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(bank, write_p, bank->bus_width, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2488,7 +2478,7 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of LOG_INFO("Fixup %" PRId32 " unaligned tail bytes", count); /* read a complete word from flash */ - retval = cfi_target_read_memory(target, write_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(bank, write_p, bank->bus_width, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2638,11 +2628,11 @@ static int cfi_probe(struct flash_bank *bank) if (retval != ERROR_OK) return retval; - retval = cfi_target_read_memory(target, flash_address(bank, 0, 0x00), + retval = cfi_target_read_memory(bank, flash_address(bank, 0, 0x00), bank->bus_width, 1, value_buf0); if (retval != ERROR_OK) return retval; - retval = cfi_target_read_memory(target, flash_address(bank, 0, 0x01), + retval = cfi_target_read_memory(bank, flash_address(bank, 0, 0x01), bank->bus_width, 1, value_buf1); if (retval != ERROR_OK) return retval; From 515a30f7200d69a41610984bee6dc4d967056ad4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 5 Jan 2020 17:26:18 +0100 Subject: [PATCH 092/354] flash/nor: Drop size argument of cfi_target_{read,write}_memory() The size argument is always set to bank->bus_width and bank pointer is now passed into cfi_target_{read,write}_memory(), so the size can be accessed through the bank pointer inside the function instead of being explicitly passed in. Change-Id: I0abc1cc3bf513281c10cb5de7a21cb0e75cb7676 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5389 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/cfi.c | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 3e265dd39..14f9b1130 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -132,17 +132,17 @@ static inline uint32_t flash_address(struct flash_bank *bank, int sector, uint32 } static int cfi_target_write_memory(struct flash_bank *bank, target_addr_t addr, - uint32_t size, uint32_t count, - const uint8_t *buffer) + uint32_t count, const uint8_t *buffer) { - return target_write_memory(bank->target, addr, size, count, buffer); + return target_write_memory(bank->target, addr, bank->bus_width, + count, buffer); } static int cfi_target_read_memory(struct flash_bank *bank, target_addr_t addr, - uint32_t size, uint32_t count, - uint8_t *buffer) + uint32_t count, uint8_t *buffer) { - return target_read_memory(bank->target, addr, size, count, buffer); + return target_read_memory(bank->target, addr, bank->bus_width, + count, buffer); } static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf) @@ -170,7 +170,7 @@ static int cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t addre uint8_t command[CFI_MAX_BUS_WIDTH]; cfi_command(bank, cmd, command); - return cfi_target_write_memory(bank, address, bank->bus_width, 1, command); + return cfi_target_write_memory(bank, address, 1, command); } /* read unsigned 8-bit value from the bank @@ -184,7 +184,7 @@ static int cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset, ui int retval; retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), - bank->bus_width, 1, data); + 1, data); if (retval != ERROR_OK) return retval; @@ -208,7 +208,7 @@ static int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint int retval; retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), - bank->bus_width, 1, data); + 1, data); if (retval != ERROR_OK) return retval; @@ -237,13 +237,13 @@ static int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, u uint8_t i; for (i = 0; i < 2; i++) { retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset + i), - bank->bus_width, 1, &data[i * bank->bus_width]); + 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) return retval; } } else { retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), - bank->bus_width, 2, data); + 2, data); if (retval != ERROR_OK) return retval; } @@ -266,13 +266,13 @@ static int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, u uint8_t i; for (i = 0; i < 4; i++) { retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset + i), - bank->bus_width, 1, &data[i * bank->bus_width]); + 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) return retval; } } else { retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), - bank->bus_width, 4, data); + 4, data); if (retval != ERROR_OK) return retval; } @@ -2006,7 +2006,7 @@ static int cfi_intel_write_word(struct flash_bank *bank, uint8_t *word, uint32_t if (retval != ERROR_OK) return retval; - retval = cfi_target_write_memory(bank, address, bank->bus_width, 1, word); + retval = cfi_target_write_memory(bank, address, 1, word); if (retval != ERROR_OK) return retval; @@ -2086,7 +2086,7 @@ static int cfi_intel_write_words(struct flash_bank *bank, const uint8_t *word, if (retval != ERROR_OK) return retval; - retval = cfi_target_write_memory(bank, address, bank->bus_width, bufferwsize, word); + retval = cfi_target_write_memory(bank, address, bufferwsize, word); if (retval != ERROR_OK) return retval; @@ -2126,7 +2126,7 @@ static int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint3 if (retval != ERROR_OK) return retval; - retval = cfi_target_write_memory(bank, address, bank->bus_width, 1, word); + retval = cfi_target_write_memory(bank, address, 1, word); if (retval != ERROR_OK) return retval; @@ -2187,7 +2187,7 @@ static int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word if (retval != ERROR_OK) return retval; - retval = cfi_target_write_memory(bank, address, bank->bus_width, bufferwsize, word); + retval = cfi_target_write_memory(bank, address, bufferwsize, word); if (retval != ERROR_OK) return retval; @@ -2288,7 +2288,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u LOG_INFO("Fixup %d unaligned read head bytes", align); /* read a complete word from flash */ - retval = cfi_target_read_memory(bank, read_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(bank, read_p, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2301,7 +2301,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u align = count / bank->bus_width; if (align) { - retval = cfi_target_read_memory(bank, read_p, bank->bus_width, align, buffer); + retval = cfi_target_read_memory(bank, read_p, align, buffer); if (retval != ERROR_OK) return retval; @@ -2314,7 +2314,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u LOG_INFO("Fixup %" PRIu32 " unaligned read tail bytes", count); /* read a complete word from flash */ - retval = cfi_target_read_memory(bank, read_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(bank, read_p, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2358,7 +2358,7 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of LOG_INFO("Fixup %d unaligned head bytes", align); /* read a complete word from flash */ - retval = cfi_target_read_memory(bank, write_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(bank, write_p, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2478,7 +2478,7 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of LOG_INFO("Fixup %" PRId32 " unaligned tail bytes", count); /* read a complete word from flash */ - retval = cfi_target_read_memory(bank, write_p, bank->bus_width, 1, current_word); + retval = cfi_target_read_memory(bank, write_p, 1, current_word); if (retval != ERROR_OK) return retval; @@ -2629,11 +2629,11 @@ static int cfi_probe(struct flash_bank *bank) return retval; retval = cfi_target_read_memory(bank, flash_address(bank, 0, 0x00), - bank->bus_width, 1, value_buf0); + 1, value_buf0); if (retval != ERROR_OK) return retval; retval = cfi_target_read_memory(bank, flash_address(bank, 0, 0x01), - bank->bus_width, 1, value_buf1); + 1, value_buf1); if (retval != ERROR_OK) return retval; switch (bank->chip_width) { From 3192717ae910d387476b3a7980c325ceb0d2f733 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 13 Apr 2019 22:44:45 +0200 Subject: [PATCH 093/354] flash/nor: Allow CFI memory read/write functions be overriden Add possibility to supply custom CFI memory accessors via cfi_info and override the default memory-mapped ones. Change-Id: I1b6bc1db69fc33e8cdef96c41742c40e6d8917e9 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5147 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/cfi.c | 18 ++++++++++++++---- src/flash/nor/cfi.h | 6 ++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 14f9b1130..0437930b2 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -134,15 +134,25 @@ static inline uint32_t flash_address(struct flash_bank *bank, int sector, uint32 static int cfi_target_write_memory(struct flash_bank *bank, target_addr_t addr, uint32_t count, const uint8_t *buffer) { - return target_write_memory(bank->target, addr, bank->bus_width, - count, buffer); + struct cfi_flash_bank *cfi_info = bank->driver_priv; + if (cfi_info->write_mem) { + return cfi_info->write_mem(bank, addr, count, buffer); + } else { + return target_write_memory(bank->target, addr, bank->bus_width, + count, buffer); + } } static int cfi_target_read_memory(struct flash_bank *bank, target_addr_t addr, uint32_t count, uint8_t *buffer) { - return target_read_memory(bank->target, addr, bank->bus_width, - count, buffer); + struct cfi_flash_bank *cfi_info = bank->driver_priv; + if (cfi_info->read_mem) { + return cfi_info->read_mem(bank, addr, count, buffer); + } else { + return target_read_memory(bank->target, addr, bank->bus_width, + count, buffer); + } } static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf) diff --git a/src/flash/nor/cfi.h b/src/flash/nor/cfi.h index ed858a9de..9451faae6 100644 --- a/src/flash/nor/cfi.h +++ b/src/flash/nor/cfi.h @@ -73,6 +73,12 @@ struct cfi_flash_bank { unsigned buf_write_timeout; unsigned block_erase_timeout; unsigned chip_erase_timeout; + + /* memory accessors */ + int (*write_mem)(struct flash_bank *bank, target_addr_t addr, + uint32_t count, const uint8_t *buffer); + int (*read_mem)(struct flash_bank *bank, target_addr_t addr, + uint32_t count, uint8_t *buffer); }; /* Intel primary extended query table From 76de1c8de104496f26a1cd084b755008349fa064 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 5 Jan 2020 22:33:29 +0100 Subject: [PATCH 094/354] flash/nor: Rename get_cfi_info() to cfi_get_info() This is a preparatory change, align the function name with the rest of the API, no functional change. Change-Id: Ib967520f027b03eb1792b36ede52335df8e23941 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5390 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/cfi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 0437930b2..19c63f8eb 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -3023,7 +3023,7 @@ static int cfi_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int get_cfi_info(struct flash_bank *bank, char *buf, int buf_size) +static int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size) { int printed; struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -3134,6 +3134,6 @@ const struct flash_driver cfi_flash = { /* FIXME: access flash at bus_width size */ .erase_check = default_flash_blank_check, .protect_check = cfi_protect_check, - .info = get_cfi_info, + .info = cfi_get_info, .free_driver_priv = default_flash_free_driver_priv, }; From f22883e8c131b31b9b1bcc762b3f7317789147fb Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 5 Jan 2020 22:34:42 +0100 Subject: [PATCH 095/354] flash/nor: Rename flash_address() to cfi_flash_address() This is a preparatory change, align the function name with the rest of the API, no functional change. Change-Id: I6a810d2a54edcd13ad9a87d24a7334802c41623b Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5391 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/cfi.c | 102 ++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 19c63f8eb..bcb1f575f 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -112,7 +112,7 @@ static void cfi_fixup(struct flash_bank *bank, const struct cfi_fixup *fixups) } } -static inline uint32_t flash_address(struct flash_bank *bank, int sector, uint32_t offset) +static inline uint32_t cfi_flash_address(struct flash_bank *bank, int sector, uint32_t offset) { struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -193,7 +193,7 @@ static int cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset, ui uint8_t data[CFI_MAX_BUS_WIDTH]; int retval; - retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset), 1, data); if (retval != ERROR_OK) return retval; @@ -217,7 +217,7 @@ static int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint int i; int retval; - retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset), 1, data); if (retval != ERROR_OK) return retval; @@ -246,13 +246,13 @@ static int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, u if (cfi_info->x16_as_x8) { uint8_t i; for (i = 0; i < 2; i++) { - retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset + i), + retval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset + i), 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) return retval; } } else { - retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset), 2, data); if (retval != ERROR_OK) return retval; @@ -275,13 +275,13 @@ static int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, u if (cfi_info->x16_as_x8) { uint8_t i; for (i = 0; i < 4; i++) { - retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset + i), + retval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset + i), 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) return retval; } } else { - retval = cfi_target_read_memory(bank, flash_address(bank, sector, offset), + retval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset), 4, data); if (retval != ERROR_OK) return retval; @@ -303,11 +303,11 @@ static int cfi_reset(struct flash_bank *bank) struct cfi_flash_bank *cfi_info = bank->driver_priv; int retval = ERROR_OK; - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; @@ -315,7 +315,7 @@ static int cfi_reset(struct flash_bank *bank) (cfi_info->device_id == 0x227E || cfi_info->device_id == 0x7E)) { /* Numonix M29W128G is cmd 0xFF intolerant - causes internal undefined state * so we send an extra 0xF0 reset to fix the bug */ - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x00)); + retval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x00)); if (retval != ERROR_OK) return retval; } @@ -325,7 +325,7 @@ static int cfi_reset(struct flash_bank *bank) static void cfi_intel_clear_status_register(struct flash_bank *bank) { - cfi_send_command(bank, 0x50, flash_address(bank, 0, 0x0)); + cfi_send_command(bank, 0x50, cfi_flash_address(bank, 0, 0x0)); } static int cfi_intel_wait_status_busy(struct flash_bank *bank, int timeout, uint8_t *val) @@ -554,7 +554,7 @@ static int cfi_read_spansion_pri_ext(struct flash_bank *bank) pri_ext->_reversed_geometry = 0; if ((pri_ext->pri[0] != 'P') || (pri_ext->pri[1] != 'R') || (pri_ext->pri[2] != 'I')) { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; LOG_ERROR("Could not read spansion bank information"); @@ -661,7 +661,7 @@ static int cfi_read_atmel_pri_ext(struct flash_bank *bank) if ((atmel_pri_ext.pri[0] != 'P') || (atmel_pri_ext.pri[1] != 'R') || (atmel_pri_ext.pri[2] != 'I')) { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; LOG_ERROR("Could not read atmel bank information"); @@ -889,11 +889,11 @@ static int cfi_intel_erase(struct flash_bank *bank, int first, int last) cfi_intel_clear_status_register(bank); for (i = first; i <= last; i++) { - retval = cfi_send_command(bank, 0x20, flash_address(bank, i, 0x0)); + retval = cfi_send_command(bank, 0x20, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0xd0, flash_address(bank, i, 0x0)); + retval = cfi_send_command(bank, 0xd0, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; @@ -905,7 +905,7 @@ static int cfi_intel_erase(struct flash_bank *bank, int first, int last) if (status == 0x80) bank->sectors[i].is_erased = 1; else { - retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; @@ -915,7 +915,7 @@ static int cfi_intel_erase(struct flash_bank *bank, int first, int last) } } - return cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); + return cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); } static int cfi_spansion_unlock_seq(struct flash_bank *bank) @@ -924,11 +924,11 @@ static int cfi_spansion_unlock_seq(struct flash_bank *bank) struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, pri_ext->_unlock1)); + retval = cfi_send_command(bank, 0xaa, cfi_flash_address(bank, 0, pri_ext->_unlock1)); if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, pri_ext->_unlock2)); + retval = cfi_send_command(bank, 0x55, cfi_flash_address(bank, 0, pri_ext->_unlock2)); if (retval != ERROR_OK) return retval; @@ -947,7 +947,7 @@ static int cfi_spansion_erase(struct flash_bank *bank, int first, int last) if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0x80, flash_address(bank, 0, pri_ext->_unlock1)); + retval = cfi_send_command(bank, 0x80, cfi_flash_address(bank, 0, pri_ext->_unlock1)); if (retval != ERROR_OK) return retval; @@ -955,14 +955,14 @@ static int cfi_spansion_erase(struct flash_bank *bank, int first, int last) if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0x30, flash_address(bank, i, 0x0)); + retval = cfi_send_command(bank, 0x30, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; if (cfi_spansion_wait_status_busy(bank, cfi_info->block_erase_timeout) == ERROR_OK) bank->sectors[i].is_erased = 1; else { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; @@ -972,7 +972,7 @@ static int cfi_spansion_erase(struct flash_bank *bank, int first, int last) } } - return cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); + return cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); } static int cfi_erase(struct flash_bank *bank, int first, int last) @@ -1025,16 +1025,16 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la cfi_intel_clear_status_register(bank); for (i = first; i <= last; i++) { - retval = cfi_send_command(bank, 0x60, flash_address(bank, i, 0x0)); + retval = cfi_send_command(bank, 0x60, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; if (set) { - retval = cfi_send_command(bank, 0x01, flash_address(bank, i, 0x0)); + retval = cfi_send_command(bank, 0x01, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; bank->sectors[i].is_protected = 1; } else { - retval = cfi_send_command(bank, 0xd0, flash_address(bank, i, 0x0)); + retval = cfi_send_command(bank, 0xd0, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; bank->sectors[i].is_protected = 0; @@ -1051,7 +1051,7 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la } else { uint8_t block_status; /* read block lock bit, to verify status */ - retval = cfi_send_command(bank, 0x90, flash_address(bank, 0, 0x55)); + retval = cfi_send_command(bank, 0x90, cfi_flash_address(bank, 0, 0x55)); if (retval != ERROR_OK) return retval; retval = cfi_get_u8(bank, i, 0x2, &block_status); @@ -1062,7 +1062,7 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la LOG_ERROR( "couldn't change block lock status (set = %i, block_status = 0x%2.2x)", set, block_status); - retval = cfi_send_command(bank, 0x70, flash_address(bank, 0, 0x55)); + retval = cfi_send_command(bank, 0x70, cfi_flash_address(bank, 0, 0x55)); if (retval != ERROR_OK) return retval; uint8_t status; @@ -1099,11 +1099,11 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la if (bank->sectors[i].is_protected == 1) { cfi_intel_clear_status_register(bank); - retval = cfi_send_command(bank, 0x60, flash_address(bank, i, 0x0)); + retval = cfi_send_command(bank, 0x60, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0x01, flash_address(bank, i, 0x0)); + retval = cfi_send_command(bank, 0x01, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; @@ -1115,7 +1115,7 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la } } - return cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); + return cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); } static int cfi_protect(struct flash_bank *bank, int set, int first, int last) @@ -1587,9 +1587,9 @@ static int cfi_spansion_write_block_mips(struct flash_bank *bank, const uint8_t buf_set_u32(reg_params[2].value, 0, 32, thisrun_count / bank->bus_width); buf_set_u32(reg_params[3].value, 0, 32, cfi_command_val(bank, 0xA0)); buf_set_u32(reg_params[4].value, 0, 32, cfi_command_val(bank, 0x80)); - buf_set_u32(reg_params[6].value, 0, 32, flash_address(bank, 0, pri_ext->_unlock1)); + buf_set_u32(reg_params[6].value, 0, 32, cfi_flash_address(bank, 0, pri_ext->_unlock1)); buf_set_u32(reg_params[7].value, 0, 32, 0xaaaaaaaa); - buf_set_u32(reg_params[8].value, 0, 32, flash_address(bank, 0, pri_ext->_unlock2)); + buf_set_u32(reg_params[8].value, 0, 32, cfi_flash_address(bank, 0, pri_ext->_unlock2)); buf_set_u32(reg_params[9].value, 0, 32, 0x55555555); retval = target_run_algorithm(target, 0, NULL, 10, reg_params, @@ -1966,9 +1966,9 @@ static int cfi_spansion_write_block(struct flash_bank *bank, const uint8_t *buff buf_set_u32(reg_params[2].value, 0, 32, thisrun_count / bank->bus_width); buf_set_u32(reg_params[3].value, 0, 32, cfi_command_val(bank, 0xA0)); buf_set_u32(reg_params[4].value, 0, 32, cfi_command_val(bank, 0x80)); - buf_set_u32(reg_params[6].value, 0, 32, flash_address(bank, 0, pri_ext->_unlock1)); + buf_set_u32(reg_params[6].value, 0, 32, cfi_flash_address(bank, 0, pri_ext->_unlock1)); buf_set_u32(reg_params[7].value, 0, 32, 0xaaaaaaaa); - buf_set_u32(reg_params[8].value, 0, 32, flash_address(bank, 0, pri_ext->_unlock2)); + buf_set_u32(reg_params[8].value, 0, 32, cfi_flash_address(bank, 0, pri_ext->_unlock2)); buf_set_u32(reg_params[9].value, 0, 32, 0x55555555); retval = target_run_algorithm(target, 0, NULL, 10, reg_params, @@ -2025,7 +2025,7 @@ static int cfi_intel_write_word(struct flash_bank *bank, uint8_t *word, uint32_t if (retval != ERROR_OK) return retval; if (status != 0x80) { - retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; @@ -2079,7 +2079,7 @@ static int cfi_intel_write_words(struct flash_bank *bank, const uint8_t *word, if (retval != ERROR_OK) return retval; if (status != 0x80) { - retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; @@ -2110,7 +2110,7 @@ static int cfi_intel_write_words(struct flash_bank *bank, const uint8_t *word, return retval; if (status != 0x80) { - retval = cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; @@ -2132,7 +2132,7 @@ static int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint3 if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0xa0, flash_address(bank, 0, pri_ext->_unlock1)); + retval = cfi_send_command(bank, 0xa0, cfi_flash_address(bank, 0, pri_ext->_unlock1)); if (retval != ERROR_OK) return retval; @@ -2141,7 +2141,7 @@ static int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint3 return retval; if (cfi_spansion_wait_status_busy(bank, cfi_info->word_write_timeout) != ERROR_OK) { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; @@ -2207,7 +2207,7 @@ static int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word return retval; if (cfi_spansion_wait_status_busy(bank, cfi_info->buf_write_timeout) != ERROR_OK) { - retval = cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); + retval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); if (retval != ERROR_OK) return retval; @@ -2563,7 +2563,7 @@ static int cfi_query_string(struct flash_bank *bank, int address) struct cfi_flash_bank *cfi_info = bank->driver_priv; int retval; - retval = cfi_send_command(bank, 0x98, flash_address(bank, 0, address)); + retval = cfi_send_command(bank, 0x98, cfi_flash_address(bank, 0, address)); if (retval != ERROR_OK) return retval; @@ -2628,21 +2628,21 @@ static int cfi_probe(struct flash_bank *bank) } /* switch to read identifier codes mode ("AUTOSELECT") */ - retval = cfi_send_command(bank, 0xaa, flash_address(bank, 0, unlock1)); + retval = cfi_send_command(bank, 0xaa, cfi_flash_address(bank, 0, unlock1)); if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0x55, flash_address(bank, 0, unlock2)); + retval = cfi_send_command(bank, 0x55, cfi_flash_address(bank, 0, unlock2)); if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0x90, flash_address(bank, 0, unlock1)); + retval = cfi_send_command(bank, 0x90, cfi_flash_address(bank, 0, unlock1)); if (retval != ERROR_OK) return retval; - retval = cfi_target_read_memory(bank, flash_address(bank, 0, 0x00), + retval = cfi_target_read_memory(bank, cfi_flash_address(bank, 0, 0x00), 1, value_buf0); if (retval != ERROR_OK) return retval; - retval = cfi_target_read_memory(bank, flash_address(bank, 0, 0x01), + retval = cfi_target_read_memory(bank, cfi_flash_address(bank, 0, 0x01), 1, value_buf1); if (retval != ERROR_OK) return retval; @@ -2946,7 +2946,7 @@ static int cfi_intel_protect_check(struct flash_bank *bank) if (!(pri_ext->blk_status_reg_mask & 0x1)) return ERROR_FLASH_OPERATION_FAILED; - retval = cfi_send_command(bank, 0x90, flash_address(bank, 0, 0x55)); + retval = cfi_send_command(bank, 0x90, cfi_flash_address(bank, 0, 0x55)); if (retval != ERROR_OK) return retval; @@ -2962,7 +2962,7 @@ static int cfi_intel_protect_check(struct flash_bank *bank) bank->sectors[i].is_protected = 0; } - return cfi_send_command(bank, 0xff, flash_address(bank, 0, 0x0)); + return cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); } static int cfi_spansion_protect_check(struct flash_bank *bank) @@ -2976,7 +2976,7 @@ static int cfi_spansion_protect_check(struct flash_bank *bank) if (retval != ERROR_OK) return retval; - retval = cfi_send_command(bank, 0x90, flash_address(bank, 0, pri_ext->_unlock1)); + retval = cfi_send_command(bank, 0x90, cfi_flash_address(bank, 0, pri_ext->_unlock1)); if (retval != ERROR_OK) return retval; @@ -2992,7 +2992,7 @@ static int cfi_spansion_protect_check(struct flash_bank *bank) bank->sectors[i].is_protected = 0; } - return cfi_send_command(bank, 0xf0, flash_address(bank, 0, 0x0)); + return cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); } static int cfi_protect_check(struct flash_bank *bank) From ff6d0704ecd66343e3dab2059c89fa392e2214be Mon Sep 17 00:00:00 2001 From: Moritz Fischer Date: Thu, 3 Oct 2019 20:25:26 -0700 Subject: [PATCH 096/354] jtag: drivers: xlnx-pcie-xvc: Add support for Xilinx XVC/PCIe Add support for Xilinx Virtual Cable over PCIe JTAG controller. It is commonly used in Xilinx based PCI Express designs with JTAG IP in the FPGA fabric. Access to the JTAG registers happens via the PCI Express extended configuration space. This can be used to debug soft-cores instantiated in the FPGA fabric. The clang static checker doesn't find any new problems with this change. Change-Id: Ib12ede0d1f26dacfda808d5e05b947b640c5bde7 Signed-off-by: Moritz Fischer Reviewed-on: http://openocd.zylin.com/5314 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Marex Reviewed-by: Oleksij Rempel --- configure.ac | 21 +- doc/openocd.texi | 22 ++ src/jtag/drivers/Makefile.am | 3 + src/jtag/drivers/xlnx-pcie-xvc.c | 481 +++++++++++++++++++++++++++++++ src/jtag/interfaces.c | 6 + 5 files changed, 532 insertions(+), 1 deletion(-) create mode 100644 src/jtag/drivers/xlnx-pcie-xvc.c diff --git a/configure.ac b/configure.ac index b84e3e8f8..e86d33f88 100644 --- a/configure.ac +++ b/configure.ac @@ -142,6 +142,9 @@ m4_define([LIBFTDI_ADAPTERS], m4_define([LIBJAYLINK_ADAPTERS], [[[jlink], [SEGGER J-Link Programmer], [JLINK]]]) +m4_define([PCIE_ADAPTERS], + [[[xlnx_pcie_xvc], [Xilinx XVC/PCIe], [XLNX_PCIE_XVC]]]) + AC_ARG_ENABLE([doxygen-html], AS_HELP_STRING([--disable-doxygen-html], @@ -315,12 +318,20 @@ AC_ARG_ENABLE([sysfsgpio], AS_HELP_STRING([--enable-sysfsgpio], [Enable building support for programming driven via sysfs gpios.]), [build_sysfsgpio=$enableval], [build_sysfsgpio=no]) +AC_ARG_ENABLE([xlnx_pcie_xvc], + AS_HELP_STRING([--enable-xlnx-pcie-xvc], [Enable building support for Xilinx XVC/PCIe.]), + [build_xlnx_pcie_xvc=$enableval], [build_xlnx_pcie_xvc=no]) + AS_CASE([$host_os], [linux*], [], [ AS_IF([test "x$build_sysfsgpio" = "xyes"], [ AC_MSG_ERROR([sysfsgpio is only available on linux]) ]) + + AS_IF([test "x$build_xlnx_pcie_xvc" = "xyes"], [ + AC_MSG_ERROR([xlnx_pcie_xvc is only available on linux]) + ]) ]) AC_ARG_ENABLE([minidriver_dummy], @@ -580,6 +591,13 @@ AS_IF([test "x$build_sysfsgpio" = "xyes"], [ AC_DEFINE([BUILD_SYSFSGPIO], [0], [0 if you don't want SysfsGPIO driver.]) ]) +AS_IF([test "x$build_xlnx_pcie_xvc" = "xyes"], [ + build_xlnx_pcie_xvc=yes + AC_DEFINE([BUILD_XLNX_PCIE_XVC], [1], [1 if you want the Xilinx XVC/PCIe driver.]) +], [ + AC_DEFINE([BUILD_XLNX_PCIE_XVC], [0], [0 if you don't want Xilinx XVC/PCIe driver.]) +]) + AS_IF([test "x$build_target64" = "xyes"], [ AC_DEFINE([BUILD_TARGET64], [1], [1 if you want 64-bit addresses.]) ], [ @@ -699,6 +717,7 @@ AM_CONDITIONAL([OOCD_TRACE], [test "x$build_oocd_trace" = "xyes"]) AM_CONDITIONAL([REMOTE_BITBANG], [test "x$build_remote_bitbang" = "xyes"]) AM_CONDITIONAL([BUSPIRATE], [test "x$build_buspirate" = "xyes"]) AM_CONDITIONAL([SYSFSGPIO], [test "x$build_sysfsgpio" = "xyes"]) +AM_CONDITIONAL([XLNX_PCIE_XVC], [test "x$build_xlnx_pcie_xvc" = "xyes"]) AM_CONDITIONAL([USE_LIBUSB0], [test "x$use_libusb0" = "xyes"]) AM_CONDITIONAL([USE_LIBUSB1], [test "x$use_libusb1" = "xyes"]) AM_CONDITIONAL([IS_CYGWIN], [test "x$is_cygwin" = "xyes"]) @@ -778,7 +797,7 @@ echo OpenOCD configuration summary echo -------------------------------------------------- m4_foreach([adapter], [USB1_ADAPTERS, USB_ADAPTERS, USB0_ADAPTERS, HIDAPI_ADAPTERS, HIDAPI_USB1_ADAPTERS, LIBFTDI_ADAPTERS, - LIBJAYLINK_ADAPTERS], + LIBJAYLINK_ADAPTERS, PCIE_ADAPTERS], [s=m4_format(["%-40s"], ADAPTER_DESC([adapter])) AS_CASE([$ADAPTER_VAR([adapter])], [auto], [ diff --git a/doc/openocd.texi b/doc/openocd.texi index c526a632a..cb1c5b791 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -617,6 +617,9 @@ produced, PDF schematics are easily found and it is easy to make. @* A JTAG driver acting as a client for the JTAG VPI server interface. @* Link: @url{http://github.com/fjullien/jtag_vpi} +@item @b{xlnx_pcie_xvc} +@* A JTAG driver exposing Xilinx Virtual Cable over PCI Express to OpenOCD as JTAG interface. + @end itemize @node About Jim-Tcl @@ -3127,6 +3130,25 @@ opendous-jtag is a freely programmable USB adapter. This is the Keil ULINK v1 JTAG debugger. @end deffn +@deffn {Interface Driver} {xlnx_pcie_xvc} +This driver supports the Xilinx Virtual Cable (XVC) over PCI Express. +It is commonly found in Xilinx based PCI Express designs. It allows debugging +fabric based JTAG devices such as Cortex-M1/M3 microcontrollers. Access to this is +exposed via extended capability registers in the PCI Express configuration space. + +For more information see Xilinx PG245 (Section on From_PCIE_to_JTAG mode). + +@deffn {Config Command} {xlnx_pcie_xvc_config} device +Specifies the PCI Express device via parameter @var{device} to use. + +The correct value for @var{device} can be obtained by looking at the output +of lscpi -D (first column) for the corresponding device. + +The string will be of the format "DDDD:BB:SS.F" such as "0000:65:00.1". + +@end deffn +@end deffn + @deffn {Interface Driver} {ZY1000} This is the Zylin ZY1000 JTAG debugger. @end deffn diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index 572cd2441..7fbcd584f 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -145,6 +145,9 @@ endif if SYSFSGPIO DRIVERFILES += %D%/sysfsgpio.c endif +if XLNX_PCIE_XVC +DRIVERFILES += %D%/xlnx-pcie-xvc.c +endif if BCM2835GPIO DRIVERFILES += %D%/bcm2835gpio.c endif diff --git a/src/jtag/drivers/xlnx-pcie-xvc.c b/src/jtag/drivers/xlnx-pcie-xvc.c new file mode 100644 index 000000000..fabf0f39f --- /dev/null +++ b/src/jtag/drivers/xlnx-pcie-xvc.c @@ -0,0 +1,481 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (c) 2019 Google, LLC. + * Author: Moritz Fischer + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define PCIE_EXT_CAP_LST 0x100 + +#define XLNX_XVC_EXT_CAP 0x00 +#define XLNX_XVC_VSEC_HDR 0x04 +#define XLNX_XVC_LEN_REG 0x0C +#define XLNX_XVC_TMS_REG 0x10 +#define XLNX_XVC_TDx_REG 0x14 + +#define XLNX_XVC_CAP_SIZE 0x20 +#define XLNX_XVC_VSEC_ID 0x8 +#define XLNX_XVC_MAX_BITS 0x20 + +struct xlnx_pcie_xvc { + int fd; + unsigned offset; + char *device; +}; + +static struct xlnx_pcie_xvc xlnx_pcie_xvc_state; +static struct xlnx_pcie_xvc *xlnx_pcie_xvc = &xlnx_pcie_xvc_state; + +static int xlnx_pcie_xvc_read_reg(const int offset, uint32_t *val) +{ + uint32_t res; + int err; + + /* Note: This should be ok endianess-wise because by going + * through sysfs the kernel does the conversion in the config + * space accessor functions + */ + err = pread(xlnx_pcie_xvc->fd, &res, sizeof(res), + xlnx_pcie_xvc->offset + offset); + if (err != sizeof(res)) { + LOG_ERROR("Failed to read offset %x", offset); + return ERROR_JTAG_DEVICE_ERROR; + } + + if (val) + *val = res; + + return ERROR_OK; +} + +static int xlnx_pcie_xvc_write_reg(const int offset, const uint32_t val) +{ + int err; + + /* Note: This should be ok endianess-wise because by going + * through sysfs the kernel does the conversion in the config + * space accessor functions + */ + err = pwrite(xlnx_pcie_xvc->fd, &val, sizeof(val), + xlnx_pcie_xvc->offset + offset); + if (err != sizeof(val)) { + LOG_ERROR("Failed to write offset: %x with value: %x", + offset, val); + return ERROR_JTAG_DEVICE_ERROR; + } + + return ERROR_OK; +} + +static int xlnx_pcie_xvc_transact(size_t num_bits, uint32_t tms, uint32_t tdi, + uint32_t *tdo) +{ + int err; + + err = xlnx_pcie_xvc_write_reg(XLNX_XVC_LEN_REG, num_bits); + if (err != ERROR_OK) + return err; + + err = xlnx_pcie_xvc_write_reg(XLNX_XVC_TMS_REG, tms); + if (err != ERROR_OK) + return err; + + err = xlnx_pcie_xvc_write_reg(XLNX_XVC_TDx_REG, tdi); + if (err != ERROR_OK) + return err; + + err = xlnx_pcie_xvc_read_reg(XLNX_XVC_TDx_REG, tdo); + if (err != ERROR_OK) + return err; + + if (tdo) + LOG_DEBUG_IO("Transact num_bits: %zu, tms: %x, tdi: %x, tdo: %x", + num_bits, tms, tdi, *tdo); + else + LOG_DEBUG_IO("Transact num_bits: %zu, tms: %x, tdi: %x, tdo: ", + num_bits, tms, tdi); + return ERROR_OK; +} + +int xlnx_pcie_xvc_execute_stableclocks(struct jtag_command *cmd) +{ + int tms = tap_get_state() == TAP_RESET ? 1 : 0; + size_t left = cmd->cmd.stableclocks->num_cycles; + size_t write; + int err; + + LOG_DEBUG("stableclocks %i cycles", cmd->cmd.runtest->num_cycles); + + while (left) { + write = MIN(XLNX_XVC_MAX_BITS, left); + err = xlnx_pcie_xvc_transact(write, tms, 0, NULL); + if (err != ERROR_OK) + return err; + left -= write; + }; + + return ERROR_OK; +} + +static int xlnx_pcie_xvc_execute_statemove(size_t skip) +{ + uint8_t tms_scan = tap_get_tms_path(tap_get_state(), + tap_get_end_state()); + int tms_count = tap_get_tms_path_len(tap_get_state(), + tap_get_end_state()); + int err; + + LOG_DEBUG("statemove starting at (skip: %zu) %s end in %s", skip, + tap_state_name(tap_get_state()), + tap_state_name(tap_get_end_state())); + + + err = xlnx_pcie_xvc_transact(tms_count - skip, tms_scan >> skip, 0, NULL); + if (err != ERROR_OK) + return err; + + tap_set_state(tap_get_end_state()); + + return ERROR_OK; +} + +static int xlnx_pcie_xvc_execute_runtest(struct jtag_command *cmd) +{ + int err = ERROR_OK; + + LOG_DEBUG("runtest %i cycles, end in %i", + cmd->cmd.runtest->num_cycles, + cmd->cmd.runtest->end_state); + + tap_state_t tmp_state = tap_get_end_state(); + + if (tap_get_state() != TAP_IDLE) { + tap_set_end_state(TAP_IDLE); + err = xlnx_pcie_xvc_execute_statemove(0); + if (err != ERROR_OK) + return err; + }; + + size_t left = cmd->cmd.runtest->num_cycles; + size_t write; + + while (left) { + write = MIN(XLNX_XVC_MAX_BITS, left); + err = xlnx_pcie_xvc_transact(write, 0, 0, NULL); + if (err != ERROR_OK) + return err; + left -= write; + }; + + tap_set_end_state(tmp_state); + if (tap_get_state() != tap_get_end_state()) + err = xlnx_pcie_xvc_execute_statemove(0); + + return err; +} + +static int xlnx_pcie_xvc_execute_pathmove(struct jtag_command *cmd) +{ + size_t num_states = cmd->cmd.pathmove->num_states; + tap_state_t *path = cmd->cmd.pathmove->path; + int err = ERROR_OK; + size_t i; + + LOG_DEBUG("pathmove: %i states, end in %i", + cmd->cmd.pathmove->num_states, + cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); + + for (i = 0; i < num_states; i++) { + if (path[i] == tap_state_transition(tap_get_state(), false)) { + err = xlnx_pcie_xvc_transact(1, 1, 0, NULL); + } else if (path[i] == tap_state_transition(tap_get_state(), true)) { + err = xlnx_pcie_xvc_transact(1, 0, 0, NULL); + } else { + LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition.", + tap_state_name(tap_get_state()), + tap_state_name(path[i])); + err = ERROR_JTAG_QUEUE_FAILED; + } + if (err != ERROR_OK) + return err; + tap_set_state(path[i]); + } + + tap_set_end_state(tap_get_state()); + + return ERROR_OK; +} + +static int xlnx_pcie_xvc_execute_scan(struct jtag_command *cmd) +{ + enum scan_type type = jtag_scan_type(cmd->cmd.scan); + tap_state_t saved_end_state = cmd->cmd.scan->end_state; + bool ir_scan = cmd->cmd.scan->ir_scan; + uint32_t tdi, tms, tdo; + uint8_t *buf, *rd_ptr; + int err, scan_size; + size_t write; + size_t left; + + scan_size = jtag_build_buffer(cmd->cmd.scan, &buf); + rd_ptr = buf; + LOG_DEBUG("%s scan type %d %d bits; starts in %s end in %s", + (cmd->cmd.scan->ir_scan) ? "IR" : "DR", type, scan_size, + tap_state_name(tap_get_state()), + tap_state_name(cmd->cmd.scan->end_state)); + + /* If we're in TAP_DR_SHIFT state but need to do a IR_SCAN or + * vice-versa, do a statemove to corresponding other state, then restore + * end state + */ + if (ir_scan && tap_get_state() != TAP_IRSHIFT) { + tap_set_end_state(TAP_IRSHIFT); + err = xlnx_pcie_xvc_execute_statemove(0); + if (err != ERROR_OK) + goto out_err; + tap_set_end_state(saved_end_state); + } else if (!ir_scan && (tap_get_state() != TAP_DRSHIFT)) { + tap_set_end_state(TAP_DRSHIFT); + err = xlnx_pcie_xvc_execute_statemove(0); + if (err != ERROR_OK) + goto out_err; + tap_set_end_state(saved_end_state); + } + + left = scan_size; + while (left) { + write = MIN(XLNX_XVC_MAX_BITS, left); + /* the last TMS should be a 1, to leave the state */ + tms = left <= XLNX_XVC_MAX_BITS ? BIT(write - 1) : 0; + tdi = (type != SCAN_IN) ? buf_get_u32(rd_ptr, 0, write) : 0; + err = xlnx_pcie_xvc_transact(write, tms, tdi, type != SCAN_OUT ? + &tdo : NULL); + if (err != ERROR_OK) + goto out_err; + left -= write; + if (type != SCAN_OUT) + buf_set_u32(rd_ptr, 0, write, tdo); + rd_ptr += sizeof(uint32_t); + }; + + err = jtag_read_buffer(buf, cmd->cmd.scan); + if (buf) + free(buf); + + if (tap_get_state() != tap_get_end_state()) + err = xlnx_pcie_xvc_execute_statemove(1); + + return err; + +out_err: + if (buf) + free(buf); + return err; +} + +static void xlnx_pcie_xvc_execute_reset(struct jtag_command *cmd) +{ + LOG_DEBUG("reset trst: %i srst: %i", cmd->cmd.reset->trst, + cmd->cmd.reset->srst); +} + +static void xlnx_pcie_xvc_execute_sleep(struct jtag_command *cmd) +{ + LOG_DEBUG("sleep %" PRIi32 "", cmd->cmd.sleep->us); + usleep(cmd->cmd.sleep->us); +} + +static int xlnx_pcie_xvc_execute_tms(struct jtag_command *cmd) +{ + const size_t num_bits = cmd->cmd.tms->num_bits; + const uint8_t *bits = cmd->cmd.tms->bits; + size_t left, write; + uint32_t tms; + int err; + + LOG_DEBUG("execute tms %zu", num_bits); + + left = num_bits; + while (left) { + write = MIN(XLNX_XVC_MAX_BITS, left); + tms = buf_get_u32(bits, 0, write); + err = xlnx_pcie_xvc_transact(write, tms, 0, NULL); + if (err != ERROR_OK) + return err; + left -= write; + bits += 4; + }; + + return ERROR_OK; +} + +static int xlnx_pcie_xvc_execute_command(struct jtag_command *cmd) +{ + LOG_DEBUG("%s: cmd->type: %u", __func__, cmd->type); + switch (cmd->type) { + case JTAG_STABLECLOCKS: + return xlnx_pcie_xvc_execute_stableclocks(cmd); + case JTAG_RUNTEST: + return xlnx_pcie_xvc_execute_runtest(cmd); + case JTAG_TLR_RESET: + tap_set_end_state(cmd->cmd.statemove->end_state); + return xlnx_pcie_xvc_execute_statemove(0); + case JTAG_PATHMOVE: + return xlnx_pcie_xvc_execute_pathmove(cmd); + case JTAG_SCAN: + return xlnx_pcie_xvc_execute_scan(cmd); + case JTAG_RESET: + xlnx_pcie_xvc_execute_reset(cmd); + break; + case JTAG_SLEEP: + xlnx_pcie_xvc_execute_sleep(cmd); + break; + case JTAG_TMS: + return xlnx_pcie_xvc_execute_tms(cmd); + default: + LOG_ERROR("BUG: Unknown JTAG command type encountered."); + return ERROR_JTAG_QUEUE_FAILED; + } + + return ERROR_OK; +} + +static int xlnx_pcie_xvc_execute_queue(void) +{ + struct jtag_command *cmd = jtag_command_queue; + int ret; + + while (cmd) { + ret = xlnx_pcie_xvc_execute_command(cmd); + + if (ret != ERROR_OK) + return ret; + + cmd = cmd->next; + } + + return ERROR_OK; +} + + +static int xlnx_pcie_xvc_init(void) +{ + char filename[PATH_MAX]; + uint32_t cap, vh; + int err; + + snprintf(filename, PATH_MAX, "/sys/bus/pci/devices/%s/config", + xlnx_pcie_xvc->device); + xlnx_pcie_xvc->fd = open(filename, O_RDWR | O_SYNC); + if (xlnx_pcie_xvc->fd < 0) { + LOG_ERROR("Failed to open device: %s", filename); + return ERROR_JTAG_INIT_FAILED; + } + + LOG_INFO("Scanning PCIe device %s's for Xilinx XVC/PCIe ...", + xlnx_pcie_xvc->device); + /* Parse the PCIe extended capability list and try to find + * vendor specific header */ + xlnx_pcie_xvc->offset = PCIE_EXT_CAP_LST; + while (xlnx_pcie_xvc->offset <= PCI_CFG_SPACE_EXP_SIZE - sizeof(cap) && + xlnx_pcie_xvc->offset >= PCIE_EXT_CAP_LST) { + err = xlnx_pcie_xvc_read_reg(XLNX_XVC_EXT_CAP, &cap); + if (err != ERROR_OK) + return err; + LOG_DEBUG("Checking capability at 0x%x; id=0x%04x version=0x%x next=0x%x", + xlnx_pcie_xvc->offset, + PCI_EXT_CAP_ID(cap), + PCI_EXT_CAP_VER(cap), + PCI_EXT_CAP_NEXT(cap)); + if (PCI_EXT_CAP_ID(cap) == PCI_EXT_CAP_ID_VNDR) { + err = xlnx_pcie_xvc_read_reg(XLNX_XVC_VSEC_HDR, &vh); + if (err != ERROR_OK) + return err; + LOG_DEBUG("Checking possible match at 0x%x; id: 0x%x; rev: 0x%x; length: 0x%x", + xlnx_pcie_xvc->offset, + PCI_VNDR_HEADER_ID(vh), + PCI_VNDR_HEADER_REV(vh), + PCI_VNDR_HEADER_LEN(vh)); + if ((PCI_VNDR_HEADER_ID(vh) == XLNX_XVC_VSEC_ID) && + (PCI_VNDR_HEADER_LEN(vh) == XLNX_XVC_CAP_SIZE)) + break; + } + xlnx_pcie_xvc->offset = PCI_EXT_CAP_NEXT(cap); + } + if ((xlnx_pcie_xvc->offset > PCI_CFG_SPACE_EXP_SIZE - XLNX_XVC_CAP_SIZE) || + xlnx_pcie_xvc->offset < PCIE_EXT_CAP_LST) { + close(xlnx_pcie_xvc->fd); + return ERROR_JTAG_INIT_FAILED; + } + + LOG_INFO("Found Xilinx XVC/PCIe capability at offset: 0x%x", xlnx_pcie_xvc->offset); + + return ERROR_OK; +} + +static int xlnx_pcie_xvc_quit(void) +{ + int err; + + err = close(xlnx_pcie_xvc->fd); + if (err) + return err; + + return ERROR_OK; +} + +COMMAND_HANDLER(xlnx_pcie_xvc_handle_config_command) +{ + if (CMD_ARGC < 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + /* we can't really free this in a safe manner, so at least + * limit the memory we're leaking by freeing the old one first + * before allocating a new one ... + */ + if (xlnx_pcie_xvc->device) + free(xlnx_pcie_xvc->device); + + xlnx_pcie_xvc->device = strdup(CMD_ARGV[0]); + return ERROR_OK; +} + +static const struct command_registration xlnx_pcie_xvc_command_handlers[] = { + { + .name = "xlnx_pcie_xvc_config", + .handler = xlnx_pcie_xvc_handle_config_command, + .mode = COMMAND_CONFIG, + .help = "Configure XVC/PCIe JTAG adapter", + .usage = "device", + }, + COMMAND_REGISTRATION_DONE +}; + +static const char * const xlnx_pcie_xvc_transports[] = { "jtag", NULL }; + +struct jtag_interface xlnx_pcie_xvc_interface = { + .name = "xlnx_pcie_xvc", + .commands = xlnx_pcie_xvc_command_handlers, + .transports = xlnx_pcie_xvc_transports, + .execute_queue = &xlnx_pcie_xvc_execute_queue, + .speed = NULL, + .speed_div = NULL, + .khz = NULL, + .init = &xlnx_pcie_xvc_init, + .quit = &xlnx_pcie_xvc_quit, +}; diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index 17d45415a..356d89ecd 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -117,6 +117,9 @@ extern struct adapter_driver opendous_adapter_driver; #if BUILD_SYSFSGPIO == 1 extern struct adapter_driver sysfsgpio_adapter_driver; #endif +#if BUILD_XLNX_PCIE_XVC == 1 +extern struct jtag_interface xlnx_pcie_xvc_interface; +#endif #if BUILD_AICE == 1 extern struct adapter_driver aice_adapter_driver; #endif @@ -225,6 +228,9 @@ struct adapter_driver *adapter_drivers[] = { #if BUILD_SYSFSGPIO == 1 &sysfsgpio_adapter_driver, #endif +#if BUILD_XLNX_PCIE_XVC == 1 + &xlnx_pcie_xvc_interface, +#endif #if BUILD_AICE == 1 &aice_adapter_driver, #endif From f98099507f509db9a18c70365490a6b9f67108db Mon Sep 17 00:00:00 2001 From: Jiri Kastner Date: Wed, 1 Aug 2018 15:17:43 +0200 Subject: [PATCH 097/354] mips_ejtag: there is no DCR.MIPS64 bit available revisions (2.60, 3.10, 5.06 and 6.10) of MD00047 (EJTAG specification), have only in IMPCODE MIPS32/MIPS64 bit/flag. Change-Id: If9191b6ced760c59bb7551bb041cd72b0a060bb1 Signed-off-by: Jiri Kastner Reviewed-on: http://openocd.zylin.com/4628 Reviewed-by: Oleksij Rempel Tested-by: jenkins --- src/target/mips_ejtag.c | 2 +- src/target/mips_ejtag.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c index 0b8122e1c..6d35e211d 100644 --- a/src/target/mips_ejtag.c +++ b/src/target/mips_ejtag.c @@ -349,7 +349,7 @@ static void ejtag_main_print_imp(struct mips_ejtag *ejtag_info) EJTAG_IMP_HAS(EJTAG_IMP_ASID6) ? " ASID_6" : "", EJTAG_IMP_HAS(EJTAG_IMP_MIPS16) ? " MIPS16" : "", EJTAG_IMP_HAS(EJTAG_IMP_NODMA) ? " noDMA" : " DMA", - EJTAG_IMP_HAS(EJTAG_DCR_MIPS64) ? " MIPS64" : " MIPS32"); + EJTAG_IMP_HAS(EJTAG_IMP_MIPS64) ? " MIPS64" : " MIPS32"); switch (ejtag_info->ejtag_version) { case EJTAG_VERSION_20: diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h index cfba0ab56..ace3d281e 100644 --- a/src/target/mips_ejtag.h +++ b/src/target/mips_ejtag.h @@ -130,7 +130,7 @@ /* v2.0 - 1:4 Number of Break Channels. */ #define EJTAG_V20_IMP_BCHANNELS_MASK 0xf #define EJTAG_V20_IMP_BCHANNELS_SHIFT 1 -#define EJTAG_DCR_MIPS64 (1 << 0) +#define EJTAG_IMP_MIPS64 (1 << 0) /* Debug Control Register DCR */ #define EJTAG_DCR 0xFF300000 From d612baacaa3fef549c446053089867d7b134ccfd Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 5 Jul 2018 13:42:14 +0200 Subject: [PATCH 098/354] jtag_libusb_bulk_read|write: return error code instead of size A USB bulk write/read operation may fail with different errors: LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates transferred) LIBUSB_ERROR_PIPE if the endpoint halted LIBUSB_ERROR_OVERFLOW if the device offered more data, see Packets and overflows LIBUSB_ERROR_NO_DEVICE if the device has been disconnected another LIBUSB_ERROR code on other failures Current OpenOCD code is using the transfer size based error detection. Which may not always work. For example for LIBUSB_ERROR_OVERFLOW as libusb documentation says: "Problems may occur if the device attempts to send more data than can fit in the buffer. libusb reports LIBUSB_TRANSFER_OVERFLOW for this condition but other behaviour is largely undefined: actual_length may or may not be accurate, the chunk of data that can fit in the buffer (before overflow) may or may not have been transferred." This patch is refactoring code to use actual error return value for error detection instead of size. Change-Id: Iec0798438ca7b5c76e2e2912af21d9aa76ee0217 Signed-off-by: Oleksij Rempel Reviewed-on: http://openocd.zylin.com/4590 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/jtag/aice/aice_usb.c | 38 ++++++++---- src/jtag/drivers/ft232r.c | 16 +++-- src/jtag/drivers/kitprog.c | 23 ++++---- src/jtag/drivers/libusb0_common.c | 42 +++++++++++-- src/jtag/drivers/libusb0_common.h | 4 +- src/jtag/drivers/libusb1_common.c | 59 +++++++++++++++---- src/jtag/drivers/libusb1_common.h | 4 +- src/jtag/drivers/opendous.c | 8 +-- src/jtag/drivers/openjtag.c | 14 ++--- src/jtag/drivers/osbdm.c | 17 +++--- src/jtag/drivers/stlink_usb.c | 29 +++++---- .../usb_blaster/ublast2_access_libusb.c | 21 +++++-- 12 files changed, 186 insertions(+), 89 deletions(-) diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index 324ec7c32..9e4741342 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -349,41 +349,53 @@ static void aice_unpack_dthmb(uint8_t *cmd_ack_code, uint8_t *target_id, /* calls the given usb_bulk_* function, allowing for the data to * trickle in with some timeouts */ static int usb_bulk_with_retries( - int (*f)(jtag_libusb_device_handle *, int, char *, int, int), + int (*f)(jtag_libusb_device_handle *, int, char *, int, int, int *), jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout) + char *bytes, int size, int timeout, int *transferred) { int tries = 3, count = 0; while (tries && (count < size)) { - int result = f(dev, ep, bytes + count, size - count, timeout); - if (result > 0) + int result, ret; + + ret = f(dev, ep, bytes + count, size - count, timeout, &result); + if (ERROR_OK == ret) count += result; - else if ((-ETIMEDOUT != result) || !--tries) - return result; + else if ((ERROR_TIMEOUT_REACHED != ret) || !--tries) + return ret; } - return count; + + *transferred = count; + return ERROR_OK; } static int wrap_usb_bulk_write(jtag_libusb_device_handle *dev, int ep, - char *buff, int size, int timeout) + char *buff, int size, int timeout, int *transferred) { + /* usb_bulk_write() takes const char *buff */ - return jtag_libusb_bulk_write(dev, ep, buff, size, timeout); + jtag_libusb_bulk_write(dev, ep, buff, size, timeout, transferred); + + return 0; } static inline int usb_bulk_write_ex(jtag_libusb_device_handle *dev, int ep, char *bytes, int size, int timeout) { - return usb_bulk_with_retries(&wrap_usb_bulk_write, - dev, ep, bytes, size, timeout); + int tr = 0; + + usb_bulk_with_retries(&wrap_usb_bulk_write, + dev, ep, bytes, size, timeout, &tr); + return tr; } static inline int usb_bulk_read_ex(jtag_libusb_device_handle *dev, int ep, char *bytes, int size, int timeout) { - return usb_bulk_with_retries(&jtag_libusb_bulk_read, - dev, ep, bytes, size, timeout); + int tr = 0; + usb_bulk_with_retries(&jtag_libusb_bulk_read, + dev, ep, bytes, size, timeout, &tr); + return tr; } /* Write data from out_buffer to USB. */ diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index 1ef0c57ea..c20367fc0 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -132,11 +132,11 @@ static int ft232r_send_recv(void) bytes_to_write = rxfifo_free; if (bytes_to_write) { - int n = jtag_libusb_bulk_write(adapter, IN_EP, - (char *) ft232r_output + total_written, - bytes_to_write, 1000); + int n; - if (n == 0) { + if (jtag_libusb_bulk_write(adapter, IN_EP, + (char *) ft232r_output + total_written, + bytes_to_write, 1000, &n) != ERROR_OK) { LOG_ERROR("usb bulk write failed"); return ERROR_JTAG_DEVICE_ERROR; } @@ -147,12 +147,10 @@ static int ft232r_send_recv(void) /* Read */ uint8_t reply[64]; + int n; - int n = jtag_libusb_bulk_read(adapter, OUT_EP, - (char *) reply, - sizeof(reply), 1000); - - if (n == 0) { + if (jtag_libusb_bulk_read(adapter, OUT_EP, (char *) reply, + sizeof(reply), 1000, &n) != ERROR_OK) { LOG_ERROR("usb bulk read failed"); return ERROR_JTAG_DEVICE_ERROR; } diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index 489441111..7b339aa0b 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -731,14 +731,14 @@ static int kitprog_swd_run_queue(void) } } - ret = jtag_libusb_bulk_write(kitprog_handle->usb_handle, - BULK_EP_OUT, (char *)buffer, write_count, 0); - if (ret > 0) { - queued_retval = ERROR_OK; - } else { + if (jtag_libusb_bulk_write(kitprog_handle->usb_handle, + BULK_EP_OUT, (char *)buffer, + write_count, 0, &ret)) { LOG_ERROR("Bulk write failed"); queued_retval = ERROR_FAIL; break; + } else { + queued_retval = ERROR_OK; } /* KitProg firmware does not send a zero length packet @@ -754,18 +754,17 @@ static int kitprog_swd_run_queue(void) if (read_count % 64 == 0) read_count_workaround = read_count; - ret = jtag_libusb_bulk_read(kitprog_handle->usb_handle, + if (jtag_libusb_bulk_read(kitprog_handle->usb_handle, BULK_EP_IN | LIBUSB_ENDPOINT_IN, (char *)buffer, - read_count_workaround, 1000); - if (ret > 0) { + read_count_workaround, 1000, &ret)) { + LOG_ERROR("Bulk read failed"); + queued_retval = ERROR_FAIL; + break; + } else { /* Handle garbage data by offsetting the initial read index */ if ((unsigned int)ret > read_count) read_index = ret - read_count; queued_retval = ERROR_OK; - } else { - LOG_ERROR("Bulk read failed"); - queued_retval = ERROR_FAIL; - break; } for (int i = 0; i < pending_transfer_count; i++) { diff --git a/src/jtag/drivers/libusb0_common.c b/src/jtag/drivers/libusb0_common.c index 14a8b61cc..0e7858911 100644 --- a/src/jtag/drivers/libusb0_common.c +++ b/src/jtag/drivers/libusb0_common.c @@ -23,6 +23,18 @@ #include "log.h" #include "libusb0_common.h" +static int jtag_libusb_error(int err) +{ + switch (err) { + case 0: + return ERROR_OK; + case -ETIMEDOUT: + return ERROR_TIMEOUT_REACHED; + default: + return ERROR_FAIL; + } +} + static bool jtag_libusb_match(struct jtag_libusb_device *dev, const uint16_t vids[], const uint16_t pids[]) { @@ -130,15 +142,37 @@ int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t request } int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) + int size, int timeout, int *transferred) { - return usb_bulk_write(dev, ep, bytes, size, timeout); + int ret; + + *transferred = 0; + + ret = usb_bulk_write(dev, ep, bytes, size, timeout); + + if (ret < 0) { + LOG_ERROR("usb_bulk_write error: %i", ret); + return jtag_libusb_error(ret); + } + + return ERROR_OK; } int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) + int size, int timeout, int *transferred) { - return usb_bulk_read(dev, ep, bytes, size, timeout); + int ret; + + *transferred = 0; + + ret = usb_bulk_read(dev, ep, bytes, size, timeout); + + if (ret < 0) { + LOG_ERROR("usb_bulk_read error: %i", ret); + return jtag_libusb_error(ret); + } + + return ERROR_OK; } int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, diff --git a/src/jtag/drivers/libusb0_common.h b/src/jtag/drivers/libusb0_common.h index 676f43acd..6f632c462 100644 --- a/src/jtag/drivers/libusb0_common.h +++ b/src/jtag/drivers/libusb0_common.h @@ -60,9 +60,9 @@ int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t requestType, uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout); int jtag_libusb_bulk_write(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout); + char *bytes, int size, int timeout, int *transferred); int jtag_libusb_bulk_read(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout); + char *bytes, int size, int timeout, int *transferred); int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, int configuration); int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, diff --git a/src/jtag/drivers/libusb1_common.c b/src/jtag/drivers/libusb1_common.c index d96ac7692..0d4bcbab6 100644 --- a/src/jtag/drivers/libusb1_common.c +++ b/src/jtag/drivers/libusb1_common.c @@ -33,6 +33,31 @@ static struct libusb_context *jtag_libusb_context; /**< Libusb context **/ static libusb_device **devs; /**< The usb device list **/ +static int jtag_libusb_error(int err) +{ + switch (err) { + case LIBUSB_SUCCESS: + return ERROR_OK; + case LIBUSB_ERROR_TIMEOUT: + return ERROR_TIMEOUT_REACHED; + case LIBUSB_ERROR_IO: + case LIBUSB_ERROR_INVALID_PARAM: + case LIBUSB_ERROR_ACCESS: + case LIBUSB_ERROR_NO_DEVICE: + case LIBUSB_ERROR_NOT_FOUND: + case LIBUSB_ERROR_BUSY: + case LIBUSB_ERROR_OVERFLOW: + case LIBUSB_ERROR_PIPE: + case LIBUSB_ERROR_INTERRUPTED: + case LIBUSB_ERROR_NO_MEM: + case LIBUSB_ERROR_NOT_SUPPORTED: + case LIBUSB_ERROR_OTHER: + return ERROR_FAIL; + default: + return ERROR_FAIL; + } +} + static bool jtag_libusb_match(struct libusb_device_descriptor *dev_desc, const uint16_t vids[], const uint16_t pids[]) { @@ -179,23 +204,37 @@ int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t request } int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) + int size, int timeout, int *transferred) { - int transferred = 0; + int ret; - libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, - &transferred, timeout); - return transferred; + *transferred = 0; + + ret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, + transferred, timeout); + if (ret != LIBUSB_SUCCESS) { + LOG_ERROR("libusb_bulk_write error: %s", libusb_error_name(ret)); + return jtag_libusb_error(ret); + } + + return ERROR_OK; } int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) + int size, int timeout, int *transferred) { - int transferred = 0; + int ret; - libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, - &transferred, timeout); - return transferred; + *transferred = 0; + + ret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, + transferred, timeout); + if (ret != LIBUSB_SUCCESS) { + LOG_ERROR("libusb_bulk_read error: %s", libusb_error_name(ret)); + return jtag_libusb_error(ret); + } + + return ERROR_OK; } int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, diff --git a/src/jtag/drivers/libusb1_common.h b/src/jtag/drivers/libusb1_common.h index 7c73d29a4..34be691f5 100644 --- a/src/jtag/drivers/libusb1_common.h +++ b/src/jtag/drivers/libusb1_common.h @@ -53,9 +53,9 @@ int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t requestType, uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout); int jtag_libusb_bulk_write(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout); + char *bytes, int size, int timeout, int *transferred); int jtag_libusb_bulk_read(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout); + char *bytes, int size, int timeout, int *transferred); int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, int configuration); /** diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index 539f475bd..d5c279b08 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -770,8 +770,8 @@ int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length) LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT, FUNC_WRITE_DATA, 0, 0, (char *) usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT); } else { - result = jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT, \ - (char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT); + jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT, \ + (char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT, &result); } #ifdef _DEBUG_USB_COMMS_ LOG_DEBUG("USB write end: %d bytes", result); @@ -797,8 +797,8 @@ int opendous_usb_read(struct opendous_jtag *opendous_jtag) LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, FUNC_READ_DATA, 0, 0, (char *) usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT); } else { - result = jtag_libusb_bulk_read(opendous_jtag->usb_handle, OPENDOUS_READ_ENDPOINT, - (char *)usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT); + jtag_libusb_bulk_read(opendous_jtag->usb_handle, OPENDOUS_READ_ENDPOINT, + (char *)usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT, &result); } #ifdef _DEBUG_USB_COMMS_ LOG_DEBUG("USB read end: %d bytes", result); diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 24960a8d9..c42b620bb 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -256,10 +256,9 @@ static int openjtag_buf_write_cy7c65215( return ERROR_JTAG_DEVICE_ERROR; } - ret = jtag_libusb_bulk_write(usbh, ep_out, (char *)buf, size, - CY7C65215_USB_TIMEOUT); - if (ret < 0) { - LOG_ERROR("bulk write failed, error %d", ret); + if (jtag_libusb_bulk_write(usbh, ep_out, (char *)buf, size, + CY7C65215_USB_TIMEOUT, &ret)) { + LOG_ERROR("bulk write failed, error"); return ERROR_JTAG_DEVICE_ERROR; } *bytes_written = ret; @@ -324,10 +323,9 @@ static int openjtag_buf_read_cy7c65215( return ERROR_JTAG_DEVICE_ERROR; } - ret = jtag_libusb_bulk_read(usbh, ep_in, (char *)buf, qty, - CY7C65215_USB_TIMEOUT); - if (ret < 0) { - LOG_ERROR("bulk read failed, error %d", ret); + if (jtag_libusb_bulk_read(usbh, ep_in, (char *)buf, qty, + CY7C65215_USB_TIMEOUT, &ret)) { + LOG_ERROR("bulk read failed, error"); return ERROR_JTAG_DEVICE_ERROR; } *bytes_read = ret; diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index ed89a7946..9a570b098 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -144,10 +144,12 @@ static struct osbdm osbdm_context; static int osbdm_send_and_recv(struct osbdm *osbdm) { /* Send request */ - int count = jtag_libusb_bulk_write(osbdm->devh, OSBDM_USB_EP_WRITE, - (char *)osbdm->buffer, osbdm->count, OSBDM_USB_TIMEOUT); + int count, ret; - if (count != osbdm->count) { + ret = jtag_libusb_bulk_write(osbdm->devh, OSBDM_USB_EP_WRITE, + (char *)osbdm->buffer, osbdm->count, + OSBDM_USB_TIMEOUT, &count); + if (ret || count != osbdm->count) { LOG_ERROR("OSBDM communication error: can't write"); return ERROR_FAIL; } @@ -156,13 +158,12 @@ static int osbdm_send_and_recv(struct osbdm *osbdm) uint8_t cmd_saved = osbdm->buffer[0]; /* Reading answer */ - osbdm->count = jtag_libusb_bulk_read(osbdm->devh, OSBDM_USB_EP_READ, - (char *)osbdm->buffer, OSBDM_USB_BUFSIZE, OSBDM_USB_TIMEOUT); - + ret = jtag_libusb_bulk_read(osbdm->devh, OSBDM_USB_EP_READ, + (char *)osbdm->buffer, OSBDM_USB_BUFSIZE, + OSBDM_USB_TIMEOUT, &osbdm->count); /* Now perform basic checks for data sent by BDM device */ - - if (osbdm->count < 0) { + if (ret) { LOG_ERROR("OSBDM communication error: can't read"); return ERROR_FAIL; } diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 5c904d4ff..8e4493ed8 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -531,14 +531,16 @@ static int jtag_libusb_bulk_transfer_n( static int stlink_usb_xfer_v1_get_status(void *handle) { struct stlink_usb_handle_s *h = handle; + int tr, ret; assert(handle != NULL); /* read status */ memset(h->cmdbuf, 0, STLINK_SG_SIZE); - if (jtag_libusb_bulk_read(h->fd, h->rx_ep, (char *)h->cmdbuf, - 13, STLINK_READ_TIMEOUT) != 13) + ret = jtag_libusb_bulk_read(h->fd, h->rx_ep, (char *)h->cmdbuf, 13, + STLINK_READ_TIMEOUT, &tr); + if (ret || tr != 13) return ERROR_FAIL; uint32_t t1; @@ -602,23 +604,26 @@ static int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int static int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int size) { struct stlink_usb_handle_s *h = handle; + int tr, ret; assert(handle != NULL); - if (jtag_libusb_bulk_write(h->fd, h->tx_ep, (char *)h->cmdbuf, cmdsize, - STLINK_WRITE_TIMEOUT) != cmdsize) { + ret = jtag_libusb_bulk_write(h->fd, h->tx_ep, (char *)h->cmdbuf, + cmdsize, STLINK_WRITE_TIMEOUT, &tr); + if (ret || tr != cmdsize) return ERROR_FAIL; - } if (h->direction == h->tx_ep && size) { - if (jtag_libusb_bulk_write(h->fd, h->tx_ep, (char *)buf, - size, STLINK_WRITE_TIMEOUT) != size) { + ret = jtag_libusb_bulk_write(h->fd, h->tx_ep, (char *)buf, + size, STLINK_WRITE_TIMEOUT, &tr); + if (ret || tr != size) { LOG_DEBUG("bulk write failed"); return ERROR_FAIL; } } else if (h->direction == h->rx_ep && size) { - if (jtag_libusb_bulk_read(h->fd, h->rx_ep, (char *)buf, - size, STLINK_READ_TIMEOUT) != size) { + ret = jtag_libusb_bulk_read(h->fd, h->rx_ep, (char *)buf, + size, STLINK_READ_TIMEOUT, &tr); + if (ret || tr != size) { LOG_DEBUG("bulk read failed"); return ERROR_FAIL; } @@ -840,13 +845,15 @@ static int stlink_cmd_allow_retry(void *handle, const uint8_t *buf, int size) static int stlink_usb_read_trace(void *handle, const uint8_t *buf, int size) { struct stlink_usb_handle_s *h = handle; + int tr, ret; assert(handle != NULL); assert(h->version.flags & STLINK_F_HAS_TRACE); - if (jtag_libusb_bulk_read(h->fd, h->trace_ep, (char *)buf, - size, STLINK_READ_TIMEOUT) != size) { + ret = jtag_libusb_bulk_read(h->fd, h->trace_ep, (char *)buf, size, + STLINK_READ_TIMEOUT, &tr); + if (ret || tr != size) { LOG_ERROR("bulk trace read failed"); return ERROR_FAIL; } diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c index d99173369..fb1e4440a 100644 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c @@ -42,25 +42,34 @@ static int ublast2_libusb_read(struct ublast_lowlevel *low, uint8_t *buf, unsigned size, uint32_t *bytes_read) { - *bytes_read = jtag_libusb_bulk_read(low->libusb_dev, + int ret, tmp = 0; + + ret = jtag_libusb_bulk_read(low->libusb_dev, USBBLASTER_EPIN | \ LIBUSB_ENDPOINT_IN, (char *)buf, size, - 100); - return ERROR_OK; + 100, &tmp); + *bytes_read = tmp; + + return ret; } static int ublast2_libusb_write(struct ublast_lowlevel *low, uint8_t *buf, int size, uint32_t *bytes_written) { - *bytes_written = jtag_libusb_bulk_write(low->libusb_dev, + int ret, tmp = 0; + + ret = jtag_libusb_bulk_write(low->libusb_dev, USBBLASTER_EPOUT | \ LIBUSB_ENDPOINT_OUT, (char *)buf, size, - 100); - return ERROR_OK; + 100, &tmp); + *bytes_written = tmp; + + return ret; + } static int ublast2_write_firmware_section(struct jtag_libusb_device_handle *libusb_dev, From 8b7265700136d6035d2769531a6202295f7113a6 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 2 Apr 2019 16:44:18 +0200 Subject: [PATCH 099/354] flash/nor/sh_qspi: Add SH QSPI driver Add driver for the SH QSPI controller. This SPI controller is often connected to the boot SPI NOR flash on R-Car Gen2 platforms. Add the following two lines to board TCL file to bind the driver on R-Car Gen2 SoC and make SRAM work area available: flash bank flash0 sh_qspi 0xe6b10000 0 0 0 ${_TARGETNAME}0 cs0 ${_TARGETNAME}0 configure -work-area-phys 0xe6300000 -work-area-virt 0xe6300000 -work-area-size 0x10000 -work-area-backup 0 To install mainline U-Boot on the board, use the following procedure: proc update_uboot {} { # SPL flash erase_sector 0 0x0 0x0 flash write_bank 0 /u-boot/spl/u-boot-spl.bin 0x0 # U-Boot flash erase_sector 0 0x5 0x6 flash write_bank 0 /u-boot/u-boot.img 0x140000 } Change-Id: Ief22f61e93bcabae37f6e371156dece6c4be3459 Signed-off-by: Marek Vasut --- V2: - Add Makefile and linker script for the SH QSPI IO algorithm - Include the algorithm code instead of hard-coding it Reviewed-on: http://openocd.zylin.com/5143 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- contrib/loaders/flash/sh_qspi/Makefile | 37 + contrib/loaders/flash/sh_qspi/sh_qspi.S | 306 ++++++++ contrib/loaders/flash/sh_qspi/sh_qspi.inc | 37 + contrib/loaders/flash/sh_qspi/sh_qspi.ld | 13 + src/flash/nor/Makefile.am | 1 + src/flash/nor/drivers.c | 2 + src/flash/nor/sh_qspi.c | 912 ++++++++++++++++++++++ 7 files changed, 1308 insertions(+) create mode 100644 contrib/loaders/flash/sh_qspi/Makefile create mode 100644 contrib/loaders/flash/sh_qspi/sh_qspi.S create mode 100644 contrib/loaders/flash/sh_qspi/sh_qspi.inc create mode 100644 contrib/loaders/flash/sh_qspi/sh_qspi.ld create mode 100644 src/flash/nor/sh_qspi.c diff --git a/contrib/loaders/flash/sh_qspi/Makefile b/contrib/loaders/flash/sh_qspi/Makefile new file mode 100644 index 000000000..2bfbad1b0 --- /dev/null +++ b/contrib/loaders/flash/sh_qspi/Makefile @@ -0,0 +1,37 @@ +CROSS_COMPILE=arm-linux-gnueabihf- +BIN2C = ../../../../src/helper/bin2char.sh + +TGT = sh_qspi +ASRC += sh_qspi.S +LDS = sh_qspi.ld + +OBJS += $(ASRC:.S=.o) + +CC=$(CROSS_COMPILE)gcc +OBJCOPY=$(CROSS_COMPILE)objcopy +OBJDUMP=$(CROSS_COMPILE)objdump +LD=$(CROSS_COMPILE)ld +NM=$(CROSS_COMPILE)nm +SIZE=$(CROSS_COMPILE)size + +CFLAGS=-Os -Wall -nostartfiles -marm -nostdinc -ffreestanding -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -msoft-float -pipe -march=armv7-a -mtune=generic-armv7-a +LDFLAGS=-T$(LDS) -nostdlib -Map=$(TGT).map + +all: $(TGT).inc + +%.o: %.S + $(CC) $(CFLAGS) -c $^ -o $@ + +$(TGT).elf: $(OBJS) + $(LD) $(LDFLAGS) $^ -o $@ + +$(TGT).bin: $(TGT).elf + $(OBJCOPY) $< -O binary $@ + $(NM) -n $(TGT).elf > $(TGT).sym + $(SIZE) $(TGT).elf + +$(TGT).inc: $(TGT).bin + $(BIN2C) < $< > $@ + +clean: + rm -rf *.elf *.hex *.map *.o *.disasm *.sym diff --git a/contrib/loaders/flash/sh_qspi/sh_qspi.S b/contrib/loaders/flash/sh_qspi/sh_qspi.S new file mode 100644 index 000000000..78eb1e818 --- /dev/null +++ b/contrib/loaders/flash/sh_qspi/sh_qspi.S @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * SH QSPI (Quad SPI) driver + * Copyright (C) 2019 Marek Vasut + */ + +#define BIT(n) (1UL << (n)) +/* SH QSPI register bit masks _ */ +#define SPCR_MSTR 0x08 +#define SPCR_SPE 0x40 +#define SPSR_SPRFF 0x80 +#define SPSR_SPTEF 0x20 +#define SPPCR_IO3FV 0x04 +#define SPPCR_IO2FV 0x02 +#define SPPCR_IO1FV 0x01 +#define SPBDCR_RXBC0 BIT(0) +#define SPCMD_SCKDEN BIT(15) +#define SPCMD_SLNDEN BIT(14) +#define SPCMD_SPNDEN BIT(13) +#define SPCMD_SSLKP BIT(7) +#define SPCMD_BRDV0 BIT(2) +#define SPCMD_INIT1 SPCMD_SCKDEN | SPCMD_SLNDEN | \ + SPCMD_SPNDEN | SPCMD_SSLKP | \ + SPCMD_BRDV0 +#define SPCMD_INIT2 SPCMD_SPNDEN | SPCMD_SSLKP | \ + SPCMD_BRDV0 +#define SPBFCR_TXRST BIT(7) +#define SPBFCR_RXRST BIT(6) +#define SPBFCR_TXTRG 0x30 +#define SPBFCR_RXTRG 0x07 + +/* SH QSPI register set */ +#define SH_QSPI_SPCR 0x00 +#define SH_QSPI_SSLP 0x01 +#define SH_QSPI_SPPCR 0x02 +#define SH_QSPI_SPSR 0x03 +#define SH_QSPI_SPDR 0x04 +#define SH_QSPI_SPSCR 0x08 +#define SH_QSPI_SPSSR 0x09 +#define SH_QSPI_SPBR 0x0a +#define SH_QSPI_SPDCR 0x0b +#define SH_QSPI_SPCKD 0x0c +#define SH_QSPI_SSLND 0x0d +#define SH_QSPI_SPND 0x0e +#define SH_QSPI_DUMMY0 0x0f +#define SH_QSPI_SPCMD0 0x10 +#define SH_QSPI_SPCMD1 0x12 +#define SH_QSPI_SPCMD2 0x14 +#define SH_QSPI_SPCMD3 0x16 +#define SH_QSPI_SPBFCR 0x18 +#define SH_QSPI_DUMMY1 0x19 +#define SH_QSPI_SPBDCR 0x1a +#define SH_QSPI_SPBMUL0 0x1c +#define SH_QSPI_SPBMUL1 0x20 +#define SH_QSPI_SPBMUL2 0x24 +#define SH_QSPI_SPBMUL3 0x28 + +.syntax unified +.arm +.text + +.macro wait_for_spsr, spsrbit + 1: ldrb r12, [r0, #SH_QSPI_SPSR] + tst r12, \spsrbit + beq 1b +.endm + +.macro sh_qspi_xfer + bl sh_qspi_cs_activate + str r6, [r0, SH_QSPI_SPBMUL0] + bl sh_qspi_xfer_common + bl sh_qspi_cs_deactivate +.endm + +.macro sh_qspi_write_enable + ldr r4, =SPIFLASH_WRITE_ENABLE + adr r5, _start + add r4, r5 + mov r5, #0x0 + mov r6, #0x1 + sh_qspi_xfer +.endm + +.macro sh_qspi_wait_till_ready + 1: ldr r4, =SPIFLASH_READ_STATUS + adr r5, _start + add r4, r5 + mov r5, #0x0 + mov r6, #0x2 + sh_qspi_xfer + and r13, #0x1 + cmp r13, #0x1 + beq 1b +.endm + +/* + * r0: controller base address + * r1: data buffer base address + * r2: BIT(31) -- page program (not read) + * BIT(30) -- 4-byte address (not 3-byte) + * BIT(29) -- 512-byte page (not 256-byte) + * BIT(27:20) -- SF command + * BIT(19:0) -- amount of data to read/write + * r3: SF target address + * + * r7: data size + * r8: page size + * + * r14: lr, link register + * r15: pc, program counter + * + * Clobber: r4, r5, r6, r7, r8 + */ + +.global _start +_start: + bic r7, r2, #0xff000000 + bic r7, r7, #0x00f00000 + + and r8, r2, #(1 << 31) + cmp r8, #(1 << 31) + beq do_page_program + +/* fast read */ + + bl sh_qspi_cs_activate + + bl sh_qspi_setup_command + add r8, r6, r7 + str r8, [r0, SH_QSPI_SPBMUL0] + bl sh_qspi_xfer_common + + mov r4, #0x0 + mov r5, r1 + mov r6, r7 + bl sh_qspi_xfer_common + + bl sh_qspi_cs_deactivate + + b end + +do_page_program: + + mov r8, #0x100 + tst r2, (1 << 29) + movne r8, #0x200 + +do_pp_next_page: + /* Check if less then page bytes left. */ + cmp r7, r8 + movlt r8, r7 + + sh_qspi_write_enable + + bl sh_qspi_cs_activate + + bl sh_qspi_setup_command + str r6, [r0, SH_QSPI_SPBMUL0] + bl sh_qspi_xfer_common + + mov r4, r1 + mov r5, #0x0 + mov r6, r8 + + bl sh_qspi_xfer_common + + bl sh_qspi_cs_deactivate + + sh_qspi_wait_till_ready + + add r1, r8 + add r3, r8 + sub r7, r8 + cmp r7, #0 + + bne do_pp_next_page + +end: + bkpt #0 + +sh_qspi_cs_activate: + /* Set master mode only */ + mov r12, #SPCR_MSTR + strb r12, [r0, SH_QSPI_SPCR] + + /* Set command */ + mov r12, #SPCMD_INIT1 + strh r12, [r0, SH_QSPI_SPCMD0] + + /* Reset transfer and receive Buffer */ + ldrb r12, [r0, SH_QSPI_SPSCR] + orr r12, #(SPBFCR_TXRST | SPBFCR_RXRST) + strb r12, [r0, SH_QSPI_SPBFCR] + + /* Clear transfer and receive Buffer control bit */ + ldrb r12, [r0, SH_QSPI_SPBFCR] + bic r12, #(SPBFCR_TXRST | SPBFCR_RXRST) + strb r12, [r0, SH_QSPI_SPBFCR] + + /* Set sequence control method. Use sequence0 only */ + mov r12, #0x00 + strb r12, [r0, SH_QSPI_SPSCR] + + /* Enable SPI function */ + ldrb r12, [r0, SH_QSPI_SPCR] + orr r12, #SPCR_SPE + strb r12, [r0, SH_QSPI_SPCR] + + mov pc, lr + +sh_qspi_cs_deactivate: + /* Disable SPI function */ + ldrb r12, [r0, SH_QSPI_SPCR] + bic r12, #SPCR_SPE + strb r12, [r0, SH_QSPI_SPCR] + + mov pc, lr + +/* + * r0, controller base address + * r4, tx buffer + * r5, rx buffer + * r6, xfer len, non-zero + * + * Upon exit, r13 contains the last byte in SPDR + * + * Clobber: r11, r12, r13 + */ +sh_qspi_xfer_common: +prepcopy: + ldr r13, [r0, #SH_QSPI_SPBFCR] + orr r13, #(SPBFCR_TXTRG | SPBFCR_RXTRG) + mov r11, #32 + cmp r6, #32 + + biclt r13, #(SPBFCR_TXTRG | SPBFCR_RXTRG) + movlt r11, #1 + +copy: + str r13, [r0, #SH_QSPI_SPBFCR] + + wait_for_spsr SPSR_SPTEF + + mov r12, r11 + mov r13, #0 + cmp r4, #0 + beq 3f + +2: ldrb r13, [r4], #1 + strb r13, [r0, #SH_QSPI_SPDR] + subs r12, #1 + bne 2b + b 4f + +3: strb r13, [r0, #SH_QSPI_SPDR] + subs r12, #1 + bne 3b + +4: wait_for_spsr SPSR_SPRFF + + mov r12, r11 + cmp r5, #0 + beq 6f + +5: ldrb r13, [r0, #SH_QSPI_SPDR] + strb r13, [r5], #1 + subs r12, #1 + bne 5b + b 7f + +6: ldrb r13, [r0, #SH_QSPI_SPDR] + subs r12, #1 + bne 6b + +7: subs r6, r11 + bne prepcopy + + mov pc, lr + +sh_qspi_setup_command: + ldr r4, =SPIFLASH_SCRATCH_DATA + adr r5, _start + add r4, r5 + and r12, r2, #0x0ff00000 + lsr r12, #20 + strb r12, [r4] + mov r12, r3 + strb r12, [r4, #4] + lsr r12, #8 + strb r12, [r4, #3] + lsr r12, #8 + strb r12, [r4, #2] + lsr r12, #8 + strb r12, [r4, #1] + lsr r12, #8 + mov r5, #0x0 + mov r6, #0x4 + tst r2, (1 << 30) + movne r6, #0x5 + + mov pc, lr + +SPIFLASH_READ_STATUS: .byte 0x05 /* Read Status Register */ +SPIFLASH_WRITE_ENABLE: .byte 0x06 /* Write Enable */ +SPIFLASH_NOOP: .byte 0x00 +SPIFLASH_SCRATCH_DATA: .byte 0x00, 0x0, 0x0, 0x0, 0x0 diff --git a/contrib/loaders/flash/sh_qspi/sh_qspi.inc b/contrib/loaders/flash/sh_qspi/sh_qspi.inc new file mode 100644 index 000000000..ca913923f --- /dev/null +++ b/contrib/loaders/flash/sh_qspi/sh_qspi.inc @@ -0,0 +1,37 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0xff,0x74,0xc2,0xe3,0x0f,0x76,0xc7,0xe3,0x02,0x81,0x02,0xe2,0x02,0x01,0x58,0xe3, +0x0a,0x00,0x00,0x0a,0x32,0x00,0x00,0xeb,0x6c,0x00,0x00,0xeb,0x07,0x80,0x86,0xe0, +0x1c,0x80,0x80,0xe5,0x42,0x00,0x00,0xeb,0x00,0x40,0xa0,0xe3,0x01,0x50,0xa0,0xe1, +0x07,0x60,0xa0,0xe1,0x3e,0x00,0x00,0xeb,0x39,0x00,0x00,0xeb,0x27,0x00,0x00,0xea, +0x01,0x8c,0xa0,0xe3,0x02,0x02,0x12,0xe3,0x02,0x8c,0xa0,0x13,0x08,0x00,0x57,0xe1, +0x07,0x80,0xa0,0xb1,0xcc,0x41,0x9f,0xe5,0x60,0x50,0x4f,0xe2,0x05,0x40,0x84,0xe0, +0x00,0x50,0xa0,0xe3,0x01,0x60,0xa0,0xe3,0x1d,0x00,0x00,0xeb,0x1c,0x60,0x80,0xe5, +0x2f,0x00,0x00,0xeb,0x2a,0x00,0x00,0xeb,0x19,0x00,0x00,0xeb,0x53,0x00,0x00,0xeb, +0x1c,0x60,0x80,0xe5,0x2a,0x00,0x00,0xeb,0x01,0x40,0xa0,0xe1,0x00,0x50,0xa0,0xe3, +0x08,0x60,0xa0,0xe1,0x26,0x00,0x00,0xeb,0x21,0x00,0x00,0xeb,0x88,0x41,0x9f,0xe5, +0xa8,0x50,0x4f,0xe2,0x05,0x40,0x84,0xe0,0x00,0x50,0xa0,0xe3,0x02,0x60,0xa0,0xe3, +0x0b,0x00,0x00,0xeb,0x1c,0x60,0x80,0xe5,0x1d,0x00,0x00,0xeb,0x18,0x00,0x00,0xeb, +0x01,0xd0,0x0d,0xe2,0x01,0x00,0x5d,0xe3,0xf3,0xff,0xff,0x0a,0x08,0x10,0x81,0xe0, +0x08,0x30,0x83,0xe0,0x08,0x70,0x47,0xe0,0x00,0x00,0x57,0xe3,0xda,0xff,0xff,0x1a, +0x70,0x00,0x20,0xe1,0x08,0xc0,0xa0,0xe3,0x00,0xc0,0xc0,0xe5,0x84,0xc0,0x0e,0xe3, +0xb0,0xc1,0xc0,0xe1,0x08,0xc0,0xd0,0xe5,0xc0,0xc0,0x8c,0xe3,0x18,0xc0,0xc0,0xe5, +0x18,0xc0,0xd0,0xe5,0xc0,0xc0,0xcc,0xe3,0x18,0xc0,0xc0,0xe5,0x00,0xc0,0xa0,0xe3, +0x08,0xc0,0xc0,0xe5,0x00,0xc0,0xd0,0xe5,0x40,0xc0,0x8c,0xe3,0x00,0xc0,0xc0,0xe5, +0x0e,0xf0,0xa0,0xe1,0x00,0xc0,0xd0,0xe5,0x40,0xc0,0xcc,0xe3,0x00,0xc0,0xc0,0xe5, +0x0e,0xf0,0xa0,0xe1,0x18,0xd0,0x90,0xe5,0x37,0xd0,0x8d,0xe3,0x20,0xb0,0xa0,0xe3, +0x20,0x00,0x56,0xe3,0x37,0xd0,0xcd,0xb3,0x01,0xb0,0xa0,0xb3,0x18,0xd0,0x80,0xe5, +0x03,0xc0,0xd0,0xe5,0x20,0x00,0x1c,0xe3,0xfc,0xff,0xff,0x0a,0x0b,0xc0,0xa0,0xe1, +0x00,0xd0,0xa0,0xe3,0x00,0x00,0x54,0xe3,0x04,0x00,0x00,0x0a,0x01,0xd0,0xd4,0xe4, +0x04,0xd0,0xc0,0xe5,0x01,0xc0,0x5c,0xe2,0xfb,0xff,0xff,0x1a,0x02,0x00,0x00,0xea, +0x04,0xd0,0xc0,0xe5,0x01,0xc0,0x5c,0xe2,0xfc,0xff,0xff,0x1a,0x03,0xc0,0xd0,0xe5, +0x80,0x00,0x1c,0xe3,0xfc,0xff,0xff,0x0a,0x0b,0xc0,0xa0,0xe1,0x00,0x00,0x55,0xe3, +0x04,0x00,0x00,0x0a,0x04,0xd0,0xd0,0xe5,0x01,0xd0,0xc5,0xe4,0x01,0xc0,0x5c,0xe2, +0xfb,0xff,0xff,0x1a,0x02,0x00,0x00,0xea,0x04,0xd0,0xd0,0xe5,0x01,0xc0,0x5c,0xe2, +0xfc,0xff,0xff,0x1a,0x0b,0x60,0x56,0xe0,0xd9,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1, +0x58,0x40,0x9f,0xe5,0x77,0x5f,0x4f,0xe2,0x05,0x40,0x84,0xe0,0xff,0xc6,0x02,0xe2, +0x2c,0xca,0xa0,0xe1,0x00,0xc0,0xc4,0xe5,0x03,0xc0,0xa0,0xe1,0x04,0xc0,0xc4,0xe5, +0x2c,0xc4,0xa0,0xe1,0x03,0xc0,0xc4,0xe5,0x2c,0xc4,0xa0,0xe1,0x02,0xc0,0xc4,0xe5, +0x2c,0xc4,0xa0,0xe1,0x01,0xc0,0xc4,0xe5,0x2c,0xc4,0xa0,0xe1,0x00,0x50,0xa0,0xe3, +0x04,0x60,0xa0,0xe3,0x01,0x01,0x12,0xe3,0x05,0x60,0xa0,0x13,0x0e,0xf0,0xa0,0xe1, +0x05,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x02,0x00,0x00,0x20,0x02,0x00,0x00, +0x23,0x02,0x00,0x00, diff --git a/contrib/loaders/flash/sh_qspi/sh_qspi.ld b/contrib/loaders/flash/sh_qspi/sh_qspi.ld new file mode 100644 index 000000000..2683c520b --- /dev/null +++ b/contrib/loaders/flash/sh_qspi/sh_qspi.ld @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x0; + . = ALIGN(4); + .text : { + sh_qspi.o (.text*) + *(.text*) + } +} diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index 34f91ce1e..12bafa2c5 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -51,6 +51,7 @@ NOR_DRIVERS = \ %D%/psoc4.c \ %D%/psoc5lp.c \ %D%/psoc6.c \ + %D%/sh_qspi.c \ %D%/sim3x.c \ %D%/spi.c \ %D%/stmsmi.c \ diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index 551f389de..fb43a438d 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -66,6 +66,7 @@ extern const struct flash_driver psoc5lp_flash; extern const struct flash_driver psoc5lp_eeprom_flash; extern const struct flash_driver psoc5lp_nvl_flash; extern const struct flash_driver psoc6_flash; +extern const struct flash_driver sh_qspi_flash; extern const struct flash_driver sim3x_flash; extern const struct flash_driver stellaris_flash; extern const struct flash_driver stm32f1x_flash; @@ -136,6 +137,7 @@ static const struct flash_driver * const flash_drivers[] = { &psoc5lp_eeprom_flash, &psoc5lp_nvl_flash, &psoc6_flash, + &sh_qspi_flash, &sim3x_flash, &stellaris_flash, &stm32f1x_flash, diff --git a/src/flash/nor/sh_qspi.c b/src/flash/nor/sh_qspi.c new file mode 100644 index 000000000..931b0b176 --- /dev/null +++ b/src/flash/nor/sh_qspi.c @@ -0,0 +1,912 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * SH QSPI (Quad SPI) driver + * Copyright (C) 2019 Marek Vasut + * + * Based on U-Boot SH QSPI driver + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Nobuhiro Iwamatsu + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "imp.h" +#include "spi.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* SH QSPI register bit masks _ */ +#define SPCR_MSTR 0x08 +#define SPCR_SPE 0x40 +#define SPSR_SPRFF 0x80 +#define SPSR_SPTEF 0x20 +#define SPPCR_IO3FV 0x04 +#define SPPCR_IO2FV 0x02 +#define SPPCR_IO1FV 0x01 +#define SPBDCR_RXBC0 BIT(0) +#define SPCMD_SCKDEN BIT(15) +#define SPCMD_SLNDEN BIT(14) +#define SPCMD_SPNDEN BIT(13) +#define SPCMD_SSLKP BIT(7) +#define SPCMD_BRDV0 BIT(2) +#define SPCMD_INIT1 (SPCMD_SCKDEN | SPCMD_SLNDEN | \ + SPCMD_SPNDEN | SPCMD_SSLKP | \ + SPCMD_BRDV0) +#define SPCMD_INIT2 (SPCMD_SPNDEN | SPCMD_SSLKP | \ + SPCMD_BRDV0) +#define SPBFCR_TXRST BIT(7) +#define SPBFCR_RXRST BIT(6) +#define SPBFCR_TXTRG 0x30 +#define SPBFCR_RXTRG 0x07 + +/* SH QSPI register set */ +#define SH_QSPI_SPCR 0x00 +#define SH_QSPI_SSLP 0x01 +#define SH_QSPI_SPPCR 0x02 +#define SH_QSPI_SPSR 0x03 +#define SH_QSPI_SPDR 0x04 +#define SH_QSPI_SPSCR 0x08 +#define SH_QSPI_SPSSR 0x09 +#define SH_QSPI_SPBR 0x0a +#define SH_QSPI_SPDCR 0x0b +#define SH_QSPI_SPCKD 0x0c +#define SH_QSPI_SSLND 0x0d +#define SH_QSPI_SPND 0x0e +#define SH_QSPI_DUMMY0 0x0f +#define SH_QSPI_SPCMD0 0x10 +#define SH_QSPI_SPCMD1 0x12 +#define SH_QSPI_SPCMD2 0x14 +#define SH_QSPI_SPCMD3 0x16 +#define SH_QSPI_SPBFCR 0x18 +#define SH_QSPI_DUMMY1 0x19 +#define SH_QSPI_SPBDCR 0x1a +#define SH_QSPI_SPBMUL0 0x1c +#define SH_QSPI_SPBMUL1 0x20 +#define SH_QSPI_SPBMUL2 0x24 +#define SH_QSPI_SPBMUL3 0x28 + +struct sh_qspi_flash_bank { + const struct flash_device *dev; + uint32_t io_base; + int probed; + struct working_area *io_algorithm; + struct working_area *source; + unsigned int buffer_size; +}; + +struct sh_qspi_target { + char *name; + uint32_t tap_idcode; + uint32_t io_base; +}; + +static const struct sh_qspi_target target_devices[] = { + /* name, tap_idcode, io_base */ + { "SH QSPI", 0x4ba00477, 0xe6b10000 }, + { NULL, 0, 0 } +}; + +static int sh_qspi_init(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + uint8_t val; + int ret; + + /* QSPI initialize */ + /* Set master mode only */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SPCR, SPCR_MSTR); + if (ret != ERROR_OK) + return ret; + + /* Set SSL signal level */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SSLP, 0x00); + if (ret != ERROR_OK) + return ret; + + /* Set MOSI signal value when transfer is in idle state */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SPPCR, + SPPCR_IO3FV | SPPCR_IO2FV); + if (ret != ERROR_OK) + return ret; + + /* Set bit rate. See 58.3.8 Quad Serial Peripheral Interface */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SPBR, 0x01); + if (ret != ERROR_OK) + return ret; + + /* Disable Dummy Data Transmission */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SPDCR, 0x00); + if (ret != ERROR_OK) + return ret; + + /* Set clock delay value */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SPCKD, 0x00); + if (ret != ERROR_OK) + return ret; + + /* Set SSL negation delay value */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SSLND, 0x00); + if (ret != ERROR_OK) + return ret; + + /* Set next-access delay value */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SPND, 0x00); + if (ret != ERROR_OK) + return ret; + + /* Set equence command */ + ret = target_write_u16(target, info->io_base + SH_QSPI_SPCMD0, + SPCMD_INIT2); + if (ret != ERROR_OK) + return ret; + + /* Reset transfer and receive Buffer */ + ret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR, &val); + if (ret != ERROR_OK) + return ret; + + val |= SPBFCR_TXRST | SPBFCR_RXRST; + + ret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR, val); + if (ret != ERROR_OK) + return ret; + + /* Clear transfer and receive Buffer control bit */ + ret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR, &val); + if (ret != ERROR_OK) + return ret; + + val &= ~(SPBFCR_TXRST | SPBFCR_RXRST); + + ret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR, val); + if (ret != ERROR_OK) + return ret; + + /* Set equence control method. Use equence0 only */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SPSCR, 0x00); + if (ret != ERROR_OK) + return ret; + + /* Enable SPI function */ + ret = target_read_u8(target, info->io_base + SH_QSPI_SPCR, &val); + if (ret != ERROR_OK) + return ret; + + val |= SPCR_SPE; + + return target_write_u8(target, info->io_base + SH_QSPI_SPCR, val); +} + +static int sh_qspi_cs_activate(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + uint8_t val; + int ret; + + /* Set master mode only */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SPCR, SPCR_MSTR); + if (ret != ERROR_OK) + return ret; + + /* Set command */ + ret = target_write_u16(target, info->io_base + SH_QSPI_SPCMD0, + SPCMD_INIT1); + if (ret != ERROR_OK) + return ret; + + /* Reset transfer and receive Buffer */ + ret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR, &val); + if (ret != ERROR_OK) + return ret; + + val |= SPBFCR_TXRST | SPBFCR_RXRST; + + ret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR, val); + if (ret != ERROR_OK) + return ret; + + /* Clear transfer and receive Buffer control bit */ + ret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR, &val); + if (ret != ERROR_OK) + return ret; + + val &= ~(SPBFCR_TXRST | SPBFCR_RXRST); + + ret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR, val); + if (ret != ERROR_OK) + return ret; + + /* Set equence control method. Use equence0 only */ + ret = target_write_u8(target, info->io_base + SH_QSPI_SPSCR, 0x00); + if (ret != ERROR_OK) + return ret; + + /* Enable SPI function */ + ret = target_read_u8(target, info->io_base + SH_QSPI_SPCR, &val); + if (ret != ERROR_OK) + return ret; + + val |= SPCR_SPE; + + return target_write_u8(target, info->io_base + SH_QSPI_SPCR, val); +} + +static int sh_qspi_cs_deactivate(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + uint8_t val; + int ret; + + /* Disable SPI Function */ + ret = target_read_u8(target, info->io_base + SH_QSPI_SPCR, &val); + if (ret != ERROR_OK) + return ret; + + val &= ~SPCR_SPE; + + return target_write_u8(target, info->io_base + SH_QSPI_SPCR, val); +} + +static int sh_qspi_wait_for_bit(struct flash_bank *bank, uint8_t reg, + uint32_t mask, bool set, + unsigned long timeout) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + long long endtime; + uint8_t val; + int ret; + + endtime = timeval_ms() + timeout; + do { + ret = target_read_u8(target, info->io_base + reg, &val); + if (ret != ERROR_OK) + return ret; + + if (!set) + val = ~val; + + if ((val & mask) == mask) + return ERROR_OK; + + alive_sleep(1); + } while (timeval_ms() < endtime); + + LOG_ERROR("timeout"); + return ERROR_TIMEOUT_REACHED; +} + +static int sh_qspi_xfer_common(struct flash_bank *bank, + const uint8_t *dout, unsigned int outlen, + uint8_t *din, unsigned int inlen, + bool xfer_start, bool xfer_end) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + uint8_t tdata, rdata; + uint8_t val; + unsigned int nbyte = outlen + inlen; + int ret = 0; + + if (xfer_start) { + ret = sh_qspi_cs_activate(bank); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, info->io_base + SH_QSPI_SPBMUL0, + nbyte); + if (ret != ERROR_OK) + return ret; + + ret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR, + &val); + if (ret != ERROR_OK) + return ret; + + val &= ~(SPBFCR_TXTRG | SPBFCR_RXTRG); + + ret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR, + val); + if (ret != ERROR_OK) + return ret; + } + + while (nbyte > 0) { + ret = sh_qspi_wait_for_bit(bank, SH_QSPI_SPSR, SPSR_SPTEF, + true, 1000); + if (ret != ERROR_OK) + return ret; + + tdata = outlen ? *dout++ : 0; + ret = target_write_u8(target, info->io_base + SH_QSPI_SPDR, + tdata); + if (ret != ERROR_OK) + return ret; + + ret = sh_qspi_wait_for_bit(bank, SH_QSPI_SPSR, SPSR_SPRFF, + true, 1000); + if (ret != ERROR_OK) + return ret; + + ret = target_read_u8(target, info->io_base + SH_QSPI_SPDR, + &rdata); + if (ret != ERROR_OK) + return ret; + if (!outlen && inlen) { + *din++ = rdata; + inlen--; + } + + if (outlen) + outlen--; + + nbyte--; + } + + if (xfer_end) + return sh_qspi_cs_deactivate(bank); + else + return ERROR_OK; +} + +/* Send "write enable" command to SPI flash chip. */ +static int sh_qspi_write_enable(struct flash_bank *bank) +{ + uint8_t dout = SPIFLASH_WRITE_ENABLE; + + return sh_qspi_xfer_common(bank, &dout, 1, NULL, 0, 1, 1); +} + +/* Read the status register of the external SPI flash chip. */ +static int read_status_reg(struct flash_bank *bank, uint32_t *status) +{ + uint8_t dout = SPIFLASH_READ_STATUS; + uint8_t din; + int ret; + + ret = sh_qspi_xfer_common(bank, &dout, 1, &din, 1, 1, 1); + if (ret != ERROR_OK) + return ret; + + *status = din & 0xff; + + return ERROR_OK; +} + +/* check for WIP (write in progress) bit in status register */ +/* timeout in ms */ +static int wait_till_ready(struct flash_bank *bank, int timeout) +{ + long long endtime; + uint32_t status; + int ret; + + endtime = timeval_ms() + timeout; + do { + /* read flash status register */ + ret = read_status_reg(bank, &status); + if (ret != ERROR_OK) + return ret; + + if ((status & SPIFLASH_BSY_BIT) == 0) + return ERROR_OK; + alive_sleep(1); + } while (timeval_ms() < endtime); + + LOG_ERROR("timeout"); + return ERROR_TIMEOUT_REACHED; +} + +static int sh_qspi_erase_sector(struct flash_bank *bank, int sector) +{ + struct sh_qspi_flash_bank *info = bank->driver_priv; + bool addr4b = info->dev->size_in_bytes > (1UL << 24); + uint32_t address = (sector * info->dev->sectorsize) << + (addr4b ? 0 : 8); + uint8_t dout[5] = { + info->dev->erase_cmd, + (address >> 24) & 0xff, (address >> 16) & 0xff, + (address >> 8) & 0xff, (address >> 0) & 0xff + }; + unsigned int doutlen = addr4b ? 5 : 4; + int ret; + + /* Write Enable */ + ret = sh_qspi_write_enable(bank); + if (ret != ERROR_OK) + return ret; + + /* Erase */ + ret = sh_qspi_xfer_common(bank, dout, doutlen, NULL, 0, 1, 1); + if (ret != ERROR_OK) + return ret; + + /* Poll status register */ + return wait_till_ready(bank, 3000); +} + +static int sh_qspi_erase(struct flash_bank *bank, int first, int last) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + int retval = ERROR_OK; + int sector; + + LOG_DEBUG("%s: from sector %d to sector %d", __func__, first, last); + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if ((first < 0) || (last < first) || (last >= bank->num_sectors)) { + LOG_ERROR("Flash sector invalid"); + return ERROR_FLASH_SECTOR_INVALID; + } + + if (!info->probed) { + LOG_ERROR("Flash bank not probed"); + return ERROR_FLASH_BANK_NOT_PROBED; + } + + if (info->dev->erase_cmd == 0x00) + return ERROR_FLASH_OPER_UNSUPPORTED; + + for (sector = first; sector <= last; sector++) { + if (bank->sectors[sector].is_protected) { + LOG_ERROR("Flash sector %d protected", sector); + return ERROR_FAIL; + } + } + + for (sector = first; sector <= last; sector++) { + retval = sh_qspi_erase_sector(bank, sector); + if (retval != ERROR_OK) + break; + keep_alive(); + } + + return retval; +} + +static int sh_qspi_write(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + struct reg_param reg_params[4]; + struct arm_algorithm arm_algo; + uint32_t io_base = (uint32_t)(info->io_base); + uint32_t src_base = (uint32_t)(info->source->address); + uint32_t chunk; + bool addr4b = !!(info->dev->size_in_bytes > (1UL << 24)); + int ret = ERROR_OK; + int sector; + + LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32, + __func__, offset, count); + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (offset + count > bank->size) { + LOG_WARNING("Write pasts end of flash. Extra data discarded."); + count = bank->size - offset; + } + + if (offset & 0xff) { + LOG_ERROR("sh_qspi_write_page: unaligned write address: %08x", + offset); + return ERROR_FAIL; + } + + /* Check sector protection */ + for (sector = 0; sector < bank->num_sectors; sector++) { + /* Start offset in or before this sector? */ + /* End offset in or behind this sector? */ + struct flash_sector *bs = &bank->sectors[sector]; + + if ((offset < (bs->offset + bs->size)) && + ((offset + count - 1) >= bs->offset) && + bs->is_protected) { + LOG_ERROR("Flash sector %d protected", sector); + return ERROR_FAIL; + } + } + + LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32, + __func__, offset, count); + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (offset + count > bank->size) { + LOG_WARNING("Reads past end of flash. Extra data discarded."); + count = bank->size - offset; + } + + arm_algo.common_magic = ARM_COMMON_MAGIC; + arm_algo.core_mode = ARM_MODE_SVC; + arm_algo.core_state = ARM_STATE_ARM; + + init_reg_param(®_params[0], "r0", 32, PARAM_OUT); + init_reg_param(®_params[1], "r1", 32, PARAM_OUT); + init_reg_param(®_params[2], "r2", 32, PARAM_OUT); + init_reg_param(®_params[3], "r3", 32, PARAM_OUT); + + while (count > 0) { + chunk = (count > info->buffer_size) ? + info->buffer_size : count; + + target_write_buffer(target, info->source->address, + chunk, buffer); + + buf_set_u32(reg_params[0].value, 0, 32, io_base); + buf_set_u32(reg_params[1].value, 0, 32, src_base); + buf_set_u32(reg_params[2].value, 0, 32, + (1 << 31) | (addr4b << 30) | + (info->dev->pprog_cmd << 20) | chunk); + buf_set_u32(reg_params[3].value, 0, 32, offset); + + ret = target_run_algorithm(target, 0, NULL, 4, reg_params, + info->io_algorithm->address, + 0, 10000, &arm_algo); + if (ret != ERROR_OK) { + LOG_ERROR("error executing SH QSPI flash IO algorithm"); + ret = ERROR_FLASH_OPERATION_FAILED; + break; + } + + buffer += chunk; + offset += chunk; + count -= chunk; + } + + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_params[2]); + destroy_reg_param(®_params[3]); + + return ret; +} + +static int sh_qspi_read(struct flash_bank *bank, uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + struct reg_param reg_params[4]; + struct arm_algorithm arm_algo; + uint32_t io_base = (uint32_t)(info->io_base); + uint32_t src_base = (uint32_t)(info->source->address); + uint32_t chunk; + bool addr4b = !!(info->dev->size_in_bytes > (1UL << 24)); + int ret = ERROR_OK; + + LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32, + __func__, offset, count); + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (offset + count > bank->size) { + LOG_WARNING("Reads past end of flash. Extra data discarded."); + count = bank->size - offset; + } + + arm_algo.common_magic = ARM_COMMON_MAGIC; + arm_algo.core_mode = ARM_MODE_SVC; + arm_algo.core_state = ARM_STATE_ARM; + + init_reg_param(®_params[0], "r0", 32, PARAM_OUT); + init_reg_param(®_params[1], "r1", 32, PARAM_OUT); + init_reg_param(®_params[2], "r2", 32, PARAM_OUT); + init_reg_param(®_params[3], "r3", 32, PARAM_OUT); + + while (count > 0) { + chunk = (count > info->buffer_size) ? + info->buffer_size : count; + + buf_set_u32(reg_params[0].value, 0, 32, io_base); + buf_set_u32(reg_params[1].value, 0, 32, src_base); + buf_set_u32(reg_params[2].value, 0, 32, + (addr4b << 30) | (info->dev->read_cmd << 20) | + chunk); + buf_set_u32(reg_params[3].value, 0, 32, offset); + + ret = target_run_algorithm(target, 0, NULL, 4, reg_params, + info->io_algorithm->address, + 0, 10000, &arm_algo); + if (ret != ERROR_OK) { + LOG_ERROR("error executing SH QSPI flash IO algorithm"); + ret = ERROR_FLASH_OPERATION_FAILED; + break; + } + + target_read_buffer(target, info->source->address, + chunk, buffer); + + buffer += chunk; + offset += chunk; + count -= chunk; + } + + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_params[2]); + destroy_reg_param(®_params[3]); + + return ERROR_OK; +} + +/* Return ID of flash device */ +static int read_flash_id(struct flash_bank *bank, uint32_t *id) +{ + struct target *target = bank->target; + uint8_t dout = SPIFLASH_READ_ID; + uint8_t din[3] = { 0, 0, 0 }; + int ret; + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + ret = sh_qspi_xfer_common(bank, &dout, 1, din, 3, 1, 1); + if (ret != ERROR_OK) + return ret; + + *id = (din[0] << 0) | (din[1] << 8) | (din[2] << 16); + + if (*id == 0xffffff) { + LOG_ERROR("No SPI flash found"); + return ERROR_FAIL; + } + + return ERROR_OK; +} + +static int sh_qspi_protect(struct flash_bank *bank, int set, + int first, int last) +{ + int sector; + + for (sector = first; sector <= last; sector++) + bank->sectors[sector].is_protected = set; + + return ERROR_OK; +} + +static int sh_qspi_upload_helper(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + + /* see contrib/loaders/flash/sh_qspi.s for src */ + static const uint8_t sh_qspi_io_code[] = { +#include "../../../contrib/loaders/flash/sh_qspi/sh_qspi.inc" + }; + int ret; + + if (info->source) + target_free_working_area(target, info->source); + if (info->io_algorithm) + target_free_working_area(target, info->io_algorithm); + + /* flash write code */ + if (target_alloc_working_area(target, sizeof(sh_qspi_io_code), + &info->io_algorithm) != ERROR_OK) { + LOG_WARNING("no working area available, can't do block memory writes"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + target_write_buffer(target, info->io_algorithm->address, + sizeof(sh_qspi_io_code), sh_qspi_io_code); + + /* + * Try to allocate as big work area buffer as possible, start + * with 32 kiB and count down. If there is less than 256 Bytes + * of work area available, abort. + */ + info->buffer_size = 32768; + while (true) { + ret = target_alloc_working_area_try(target, info->buffer_size, + &info->source); + if (ret == ERROR_OK) + return ret; + + info->buffer_size /= 2; + if (info->buffer_size <= 256) { + target_free_working_area(target, info->io_algorithm); + + LOG_WARNING("no large enough working area available, can't do block memory writes"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + } + + return ERROR_OK; +} + +static int sh_qspi_probe(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct sh_qspi_flash_bank *info = bank->driver_priv; + struct flash_sector *sectors; + uint32_t id = 0; /* silence uninitialized warning */ + uint32_t sectorsize; + const struct sh_qspi_target *target_device; + int ret; + + if (info->probed) + free(bank->sectors); + + info->probed = 0; + + for (target_device = target_devices; target_device->name; + ++target_device) + if (target_device->tap_idcode == target->tap->idcode) + break; + if (!target_device->name) { + LOG_ERROR("Device ID 0x%" PRIx32 " is not known", + target->tap->idcode); + return ERROR_FAIL; + } + + info->io_base = target_device->io_base; + + LOG_DEBUG("Found device %s at address " TARGET_ADDR_FMT, + target_device->name, bank->base); + + ret = sh_qspi_upload_helper(bank); + if (ret != ERROR_OK) + return ret; + + ret = sh_qspi_init(bank); + if (ret != ERROR_OK) + return ret; + + ret = read_flash_id(bank, &id); + if (ret != ERROR_OK) + return ret; + + info->dev = NULL; + for (const struct flash_device *p = flash_devices; p->name; p++) + if (p->device_id == id) { + info->dev = p; + break; + } + + if (!info->dev) { + LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", id); + return ERROR_FAIL; + } + + LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")", + info->dev->name, info->dev->device_id); + + /* Set correct size value */ + bank->size = info->dev->size_in_bytes; + if (bank->size <= (1UL << 16)) + LOG_WARNING("device needs 2-byte addresses - not implemented"); + + /* if no sectors, treat whole bank as single sector */ + sectorsize = info->dev->sectorsize ? + info->dev->sectorsize : + info->dev->size_in_bytes; + + /* create and fill sectors array */ + bank->num_sectors = info->dev->size_in_bytes / sectorsize; + sectors = calloc(1, sizeof(*sectors) * bank->num_sectors); + if (!sectors) { + LOG_ERROR("not enough memory"); + return ERROR_FAIL; + } + + for (int sector = 0; sector < bank->num_sectors; sector++) { + sectors[sector].offset = sector * sectorsize; + sectors[sector].size = sectorsize; + sectors[sector].is_erased = 0; + sectors[sector].is_protected = 0; + } + + bank->sectors = sectors; + info->probed = 1; + return ERROR_OK; +} + +static int sh_qspi_auto_probe(struct flash_bank *bank) +{ + struct sh_qspi_flash_bank *info = bank->driver_priv; + + if (info->probed) + return ERROR_OK; + + return sh_qspi_probe(bank); +} + +static int sh_qspi_flash_blank_check(struct flash_bank *bank) +{ + /* Not implemented */ + return ERROR_OK; +} + +static int sh_qspi_protect_check(struct flash_bank *bank) +{ + /* Not implemented */ + return ERROR_OK; +} + +static int sh_qspi_get_info(struct flash_bank *bank, char *buf, int buf_size) +{ + struct sh_qspi_flash_bank *info = bank->driver_priv; + + if (!info->probed) { + snprintf(buf, buf_size, + "\nSH QSPI flash bank not probed yet\n"); + return ERROR_OK; + } + + snprintf(buf, buf_size, "\nSH QSPI flash information:\n" + " Device \'%s\' (ID 0x%08" PRIx32 ")\n", + info->dev->name, info->dev->device_id); + + return ERROR_OK; +} + +FLASH_BANK_COMMAND_HANDLER(sh_qspi_flash_bank_command) +{ + struct sh_qspi_flash_bank *info; + + LOG_DEBUG("%s", __func__); + + if (CMD_ARGC < 6 || CMD_ARGC > 7) + return ERROR_COMMAND_SYNTAX_ERROR; + + if ((CMD_ARGC == 7) && strcmp(CMD_ARGV[6], "cs0")) { + LOG_ERROR("Unknown arg: %s", CMD_ARGV[6]); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + info = calloc(1, sizeof(struct sh_qspi_flash_bank)); + if (!info) { + LOG_ERROR("not enough memory"); + return ERROR_FAIL; + } + + bank->driver_priv = info; + + return ERROR_OK; +} + +const struct flash_driver sh_qspi_flash = { + .name = "sh_qspi", + .flash_bank_command = sh_qspi_flash_bank_command, + .erase = sh_qspi_erase, + .protect = sh_qspi_protect, + .write = sh_qspi_write, + .read = sh_qspi_read, + .probe = sh_qspi_probe, + .auto_probe = sh_qspi_auto_probe, + .erase_check = sh_qspi_flash_blank_check, + .protect_check = sh_qspi_protect_check, + .info = sh_qspi_get_info, + .free_driver_priv = default_flash_free_driver_priv, +}; From 60aaf14837d39393edff0df76e426232e72988f5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 17 Jan 2020 16:44:00 +0100 Subject: [PATCH 100/354] jtag: drivers: xlnx-pcie-xvc: fix build after merge Commit [1] was submitted in gerrit well before the conflicting commit [2] get merged in master branch. While it was fine committing in master branch [1] alone, it should not be committed "as is" after [2]. Unfortunately gerrit did not complained committing [1] after [2]. The result is that master branch does not build anymore when the driver xlnx-pcie-xvc is enabled at configure time by the optional flag --enable-xlnx-pcie-xvc. Apply to the driver the required changes as in [2]. While there, remove the duplicated struct xlnx_pcie_xvc_transports and the struct field already implicitly initialized to zero. [1] ff6d0704ecd6 ("jtag: drivers: xlnx-pcie-xvc: Add support for Xilinx XVC/PCIe") [2] efd1d642220a ("adapter: switch from struct jtag_interface to adapter_driver") Change-Id: I5498479b802a231afbee1b845ae9775e1da7c728 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5402 Reviewed-by: Moritz Fischer Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- src/jtag/drivers/xlnx-pcie-xvc.c | 19 ++++++++++--------- src/jtag/interfaces.c | 4 ++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/jtag/drivers/xlnx-pcie-xvc.c b/src/jtag/drivers/xlnx-pcie-xvc.c index fabf0f39f..48b03ec83 100644 --- a/src/jtag/drivers/xlnx-pcie-xvc.c +++ b/src/jtag/drivers/xlnx-pcie-xvc.c @@ -466,16 +466,17 @@ static const struct command_registration xlnx_pcie_xvc_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -static const char * const xlnx_pcie_xvc_transports[] = { "jtag", NULL }; - -struct jtag_interface xlnx_pcie_xvc_interface = { - .name = "xlnx_pcie_xvc", - .commands = xlnx_pcie_xvc_command_handlers, - .transports = xlnx_pcie_xvc_transports, +static struct jtag_interface xlnx_pcie_xvc_interface = { .execute_queue = &xlnx_pcie_xvc_execute_queue, - .speed = NULL, - .speed_div = NULL, - .khz = NULL, +}; + +struct adapter_driver xlnx_pcie_xvc_adapter_driver = { + .name = "xlnx_pcie_xvc", + .transports = jtag_only, + .commands = xlnx_pcie_xvc_command_handlers, + .init = &xlnx_pcie_xvc_init, .quit = &xlnx_pcie_xvc_quit, + + .jtag_ops = &xlnx_pcie_xvc_interface, }; diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index 356d89ecd..00b3bb502 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -118,7 +118,7 @@ extern struct adapter_driver opendous_adapter_driver; extern struct adapter_driver sysfsgpio_adapter_driver; #endif #if BUILD_XLNX_PCIE_XVC == 1 -extern struct jtag_interface xlnx_pcie_xvc_interface; +extern struct adapter_driver xlnx_pcie_xvc_adapter_driver; #endif #if BUILD_AICE == 1 extern struct adapter_driver aice_adapter_driver; @@ -229,7 +229,7 @@ struct adapter_driver *adapter_drivers[] = { &sysfsgpio_adapter_driver, #endif #if BUILD_XLNX_PCIE_XVC == 1 - &xlnx_pcie_xvc_interface, + &xlnx_pcie_xvc_adapter_driver, #endif #if BUILD_AICE == 1 &aice_adapter_driver, From ddbd8dcf9115cfd863e07bc1a7e5eb94f6b4372f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 10 Jan 2020 04:24:59 +0100 Subject: [PATCH 101/354] flash/nor/nrf5: Fix build error on OSX The chip->hwid is uint32_t , fix the print format. This was detected by TravisCI on OSX, where this triggers a build error. Change-Id: I776a7bb50e396c8fccc24500dec4750190da7982 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5401 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Ilya Kharin --- src/flash/nor/nrf5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index d923468fd..8422589b8 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -609,7 +609,7 @@ static int nrf5_info(struct flash_bank *bank, char *buf, int buf_size) variant, &variant[2]); } else { - res = snprintf(buf, buf_size, "nRF51xxx (HWID 0x%04" PRIx16 ")", + res = snprintf(buf, buf_size, "nRF51xxx (HWID 0x%08" PRIx32 ")", chip->hwid); } if (res <= 0) From dc95dd036fd1ec8333472da752035fa3b0ebc369 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 16 Dec 2019 13:08:01 +0100 Subject: [PATCH 102/354] target/arm_cti: fix regression from Tcl_return_values series Since commit 7f260f5009a774f2d66b5f3037f8f595c6881d4d native OpenOCD command handlers should not directly use Jim_SetResult functions. The Tcl result of a native command is built as concatenation of command_print() strings and Jim_SetResult() is called after return of the command handler. Replace "wrong number of args" error messages (now not delivered to user) by simply return ERROR_COMMAND_SYNTAX_ERROR Change-Id: I40c1374a13859cefbdef68e0f1c13ab93538bd50 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5363 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/target/arm_cti.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c index d415eb3a8..1662c7e16 100644 --- a/src/target/arm_cti.c +++ b/src/target/arm_cti.c @@ -261,14 +261,11 @@ COMMAND_HANDLER(handle_cti_dump) COMMAND_HANDLER(handle_cti_enable) { struct arm_cti_object *obj = CMD_DATA; - Jim_Interp *interp = CMD_CTX->interp; struct arm_cti *cti = &obj->cti; bool on_off; - if (CMD_ARGC != 1) { - Jim_SetResultString(interp, "wrong number of args", -1); - return ERROR_FAIL; - } + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; COMMAND_PARSE_ON_OFF(CMD_ARGV[0], on_off); @@ -278,14 +275,11 @@ COMMAND_HANDLER(handle_cti_enable) COMMAND_HANDLER(handle_cti_testmode) { struct arm_cti_object *obj = CMD_DATA; - Jim_Interp *interp = CMD_CTX->interp; struct arm_cti *cti = &obj->cti; bool on_off; - if (CMD_ARGC != 1) { - Jim_SetResultString(interp, "wrong number of args", -1); - return ERROR_FAIL; - } + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; COMMAND_PARSE_ON_OFF(CMD_ARGV[0], on_off); @@ -295,15 +289,12 @@ COMMAND_HANDLER(handle_cti_testmode) COMMAND_HANDLER(handle_cti_write) { struct arm_cti_object *obj = CMD_DATA; - Jim_Interp *interp = CMD_CTX->interp; struct arm_cti *cti = &obj->cti; int offset; uint32_t value; - if (CMD_ARGC != 2) { - Jim_SetResultString(interp, "Wrong number of args", -1); - return ERROR_FAIL; - } + if (CMD_ARGC != 2) + return ERROR_COMMAND_SYNTAX_ERROR; offset = cti_find_reg_offset(CMD_ARGV[0]); if (offset < 0) @@ -317,16 +308,13 @@ COMMAND_HANDLER(handle_cti_write) COMMAND_HANDLER(handle_cti_read) { struct arm_cti_object *obj = CMD_DATA; - Jim_Interp *interp = CMD_CTX->interp; struct arm_cti *cti = &obj->cti; int offset; int retval; uint32_t value; - if (CMD_ARGC != 1) { - Jim_SetResultString(interp, "Wrong number of args", -1); - return ERROR_FAIL; - } + if (CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; offset = cti_find_reg_offset(CMD_ARGV[0]); if (offset < 0) From 634e09f4e7da02a3813ac98b77bc2a4f047debbc Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 12 Dec 2019 13:30:57 +0100 Subject: [PATCH 103/354] tcl/board: Add config for STM32WB Nucleo board Change-Id: Ic29802306c706bcf3e261c60facd01d101c9e1ce Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5358 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Tomas Vanek Reviewed-by: Ilya Kharin --- tcl/board/st_nucleo_wb55.cfg | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tcl/board/st_nucleo_wb55.cfg diff --git a/tcl/board/st_nucleo_wb55.cfg b/tcl/board/st_nucleo_wb55.cfg new file mode 100644 index 000000000..5b5b8f779 --- /dev/null +++ b/tcl/board/st_nucleo_wb55.cfg @@ -0,0 +1,11 @@ +# +# Configuration for STM32WB55 Nucleo board (STM32WB55RGV6) +# + +source [find interface/stlink.cfg] + +transport select hla_swd + +source [find target/stm32wbx.cfg] + +reset_config srst_only From c2cb4e40b80783a56d991e1e970a9fde5887551a Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sat, 14 Dec 2019 16:08:32 +0100 Subject: [PATCH 104/354] flash/nor/stm32l4x: use flash infrastructure to align write The original code paded the write chunk with random bytes by overrunning the buffer. An user can easily regard the random bytes to be a programming error. Change-Id: Ib0f47b5bc406bc6a7c32f3d929bf324a17c7c1e1 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5359 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/flash/nor/stm32l4x.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 3d1537756..1b54193c2 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -278,6 +278,10 @@ FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command) return ERROR_FAIL; /* Checkme: What better error to use?*/ bank->driver_priv = stm32l4_info; + /* The flash write must be aligned to a double word (8-bytes) boundary. + * Ask the flash infrastructure to ensure required alignment */ + bank->write_start_alignment = bank->write_end_alignment = 8; + stm32l4_info->probed = 0; return ERROR_OK; @@ -679,30 +683,15 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, return ERROR_TARGET_NOT_HALTED; } - if (offset & 0x7) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", - offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } - - if (count & 0x7) { - LOG_WARNING("Padding %d bytes to keep 8-byte write size", - count & 7); - count = (count + 7) & ~7; - /* This pads the write chunk with random bytes by overrunning the - * write buffer. Padding with the erased pattern 0xff is purely - * cosmetical, as 8-byte flash words are ECC secured and the first - * write will program the ECC bits. A second write would need - * to reprogramm these ECC bits. - * But this can only be done after erase! - */ - } + /* The flash write must be aligned to a double word (8-bytes) boundary. + * The flash infrastructure ensures it, do just a security check */ + assert(offset % 8 == 0); + assert(count % 8 == 0); retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) return retval; - /* Only full double words (8-byte) can be programmed*/ retval = stm32l4_write_block(bank, buffer, offset, count / 2); if (retval != ERROR_OK) { LOG_WARNING("block write failed"); From e7e681ac2b66b9eb585b7dfb8eed6c5bd2efefa9 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sat, 14 Dec 2019 18:55:01 +0100 Subject: [PATCH 105/354] flash/nor/stm32l4x: fix minor errors in flash write/async algo Fix comment of tested errors in asm src. List all relevant errors in FLASH_ERROR mask: FLASH_PROGERR was missing and any trial to re-program already programmed double word ended up in the error bit held uncleared and flash write permanetly repeating the error message until reset. Lock the bank also after unsuccesfull write_block run. Set async target algo block size to size of double word. Remove warning in case of write_block success. In case of error use LOG_ERROR instead of warning. Change-Id: Ibf6d5e306a4c2eaa43de67d636b4902c737f02f3 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5360 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- contrib/loaders/flash/stm32/stm32l4x.S | 2 +- src/flash/nor/stm32l4x.c | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/contrib/loaders/flash/stm32/stm32l4x.S b/contrib/loaders/flash/stm32/stm32l4x.S index 9c49016df..e0ce3cb34 100644 --- a/contrib/loaders/flash/stm32/stm32l4x.S +++ b/contrib/loaders/flash/stm32/stm32l4x.S @@ -71,7 +71,7 @@ busy: ldr r6, [r4, #STM32_FLASH_SR_OFFSET] tst r6, #0x10000 /* BSY (bit16) == 1 => operation in progress */ bne busy /* wait more... */ - tst r6, #0xfa /* PGSERR | PGPERR | PGAERR | WRPERR | PROGERR*/ + tst r6, #0xfa /* PGSERR | SIZERR | PGAERR | WRPERR | PROGERR | OPERR */ bne error /* fail... */ cmp r5, r1 /* wrap rp at end of buffer */ diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 1b54193c2..c8055cd9c 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -106,7 +106,7 @@ #define FLASH_PROGERR (1 << 3) /* Programming error */ #define FLASH_OPERR (1 << 1) /* Operation error */ #define FLASH_EOP (1 << 0) /* End of operation */ -#define FLASH_ERROR (FLASH_PGSERR | FLASH_PGSERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_OPERR) +#define FLASH_ERROR (FLASH_PGSERR | FLASH_SIZERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_PROGERR | FLASH_OPERR) /* register unlock keys */ #define KEY1 0x45670123 @@ -577,7 +577,7 @@ static int stm32l4_protect(struct flash_bank *bank, int set, int first, int last return ret; } -/* Count is in halfwords */ +/* Count is in double-words */ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { @@ -630,15 +630,15 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */ init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */ init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (double word-64bit) */ - init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* flash base */ + init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* flash regs base */ buf_set_u32(reg_params[0].value, 0, 32, source->address); buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); buf_set_u32(reg_params[2].value, 0, 32, address); - buf_set_u32(reg_params[3].value, 0, 32, count / 4); + buf_set_u32(reg_params[3].value, 0, 32, count); buf_set_u32(reg_params[4].value, 0, 32, stm32l4_info->part_info->flash_regs_base); - retval = target_run_flash_async_algorithm(target, buffer, count, 2, + retval = target_run_flash_async_algorithm(target, buffer, count, 8, 0, NULL, 5, reg_params, source->address, source->size, @@ -676,7 +676,7 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { - int retval; + int retval, retval2; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -692,14 +692,15 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, if (retval != ERROR_OK) return retval; - retval = stm32l4_write_block(bank, buffer, offset, count / 2); + retval = stm32l4_write_block(bank, buffer, offset, count / 8); + + retval2 = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); + if (retval != ERROR_OK) { - LOG_WARNING("block write failed"); + LOG_ERROR("block write failed"); return retval; } - - LOG_WARNING("block write succeeded"); - return stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); + return retval2; } static int stm32l4_read_idcode(struct flash_bank *bank, uint32_t *id) From 5280eb618a8cab4639f1eca567472db7e5024d13 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 19 Nov 2018 12:56:48 +0100 Subject: [PATCH 106/354] jtag: adapter: rework adapter related commands currently we have different types of same command group: - starting with adapter_* - starting with interface* - without adapter or interface prefix. Since interface name is already used, we can only use "adapter" command group by keeping old commands as well. Change-Id: Id0a1cb63a2ea6860c67ae1e7a3a06a37ddf464f4 Signed-off-by: Oleksij Rempel Reviewed-on: http://openocd.zylin.com/4774 Reviewed-by: Marc Schink Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Oleksij Rempel --- doc/openocd.texi | 45 +++++++------- src/jtag/adapter.c | 137 +++++++++++++++++++++++-------------------- src/jtag/startup.tcl | 47 +++++++++++++-- 3 files changed, 138 insertions(+), 91 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index cb1c5b791..b203656fc 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -1574,7 +1574,7 @@ solution just avoids using that instruction with JTAG debuggers. If both the chip and the board support adaptive clocking, use the @command{jtag_rclk} command, in case your board is used with JTAG adapter which -also supports it. Otherwise use @command{adapter_khz}. +also supports it. Otherwise use @command{adapter speed}. Set the slow rate at the beginning of the reset sequence, and the faster rate as soon as the clocks are at full speed. @@ -1614,12 +1614,12 @@ proc init_board @{@} @{ reset_config trst_and_srst trst_pulls_srst $_TARGETNAME configure -event reset-start @{ - adapter_khz 100 + adapter speed 100 @} $_TARGETNAME configure -event reset-init @{ enable_fast_clock - adapter_khz 10000 + adapter speed 10000 @} @} @end example @@ -2344,22 +2344,22 @@ interface jlink Most adapters need a bit more configuration than that. -@section Interface Configuration +@section Adapter Configuration -The interface command tells OpenOCD what type of debug adapter you are +The @command{adapter driver} 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 +@deffn {Config Command} {adapter driver} name +Use the adapter driver @var{name} to connect to the target. @end deffn -@deffn Command {interface_list} +@deffn Command {adapter list} List the debug adapter drivers that have been built into the running copy of OpenOCD. @end deffn -@deffn Command {interface transports} transport_name+ +@deffn Command {adapter transports} transport_name+ Specifies the transports supported by this debug adapter. The adapter driver builds-in similar knowledge; use this only when external configuration (such as jumpering) changes what @@ -2368,7 +2368,7 @@ the hardware can support. -@deffn Command {adapter_name} +@deffn Command {adapter name} Returns the name of the debug adapter driver being used. @end deffn @@ -2993,7 +2993,7 @@ you may encounter a problem. @deffn Command {parport_toggling_time} [nanoseconds] Displays how many nanoseconds the hardware needs to toggle TCK; the parport driver uses this value to obey the -@command{adapter_khz} configuration. +@command{adapter speed} configuration. When the optional @var{nanoseconds} parameter is given, that setting is changed before displaying the current value. @@ -3004,7 +3004,7 @@ To measure the toggling time with a logic analyzer or a digital storage oscilloscope, follow the procedure below: @example > parport_toggling_time 1000 -> adapter_khz 500 +> adapter speed 500 @end example This sets the maximum JTAG clock speed of the hardware, but the actual speed probably deviates from the requested 500 kHz. @@ -3015,14 +3015,15 @@ Update the setting to match your measurement: @example > parport_toggling_time @end example -Now the clock speed will be a better match for @command{adapter_khz rate} -commands given in OpenOCD scripts and event handlers. +Now the clock speed will be a better match for @command{adapter speed} +command given in OpenOCD scripts and event handlers. You can do something similar with many digital multimeters, but note that you'll probably need to run the clock continuously for several seconds before it decides what clock rate to show. Adjust the toggling time up or down until the measured clock rate is a good -match for the adapter_khz rate you specified; be conservative. +match with the rate you specified in the @command{adapter speed} command; +be conservative. @end quotation @end deffn @@ -3329,10 +3330,10 @@ However, it introduces delays to synchronize clocks; so it may not be the fastest solution. @b{NOTE:} Script writers should consider using @command{jtag_rclk} -instead of @command{adapter_khz}, but only for (ARM) cores and boards +instead of @command{adapter speed}, but only for (ARM) cores and boards which support adaptive clocking. -@deffn {Command} adapter_khz max_speed_kHz +@deffn {Command} adapter speed max_speed_kHz A non-zero speed is in KHZ. Hence: 3000 is 3mhz. JTAG interfaces usually support a limited number of speeds. The speed actually used won't be faster @@ -3462,7 +3463,7 @@ stops issuing the reset. For example, there may be chip or board requirements that all reset pulses last for at least a certain amount of time; and reset buttons commonly have hardware debouncing. -Use the @command{adapter_nsrst_delay} and @command{jtag_ntrst_delay} +Use the @command{adapter srst delay} and @command{jtag_ntrst_delay} commands to say when extra delays are needed. @item @emph{Drive type} ... Reset lines often have a pullup @@ -3502,13 +3503,13 @@ needing to cope with both architecture and board specific constraints. @section Commands for Handling Resets -@deffn {Command} adapter_nsrst_assert_width milliseconds +@deffn {Command} adapter srst pulse_width milliseconds Minimum amount of time (in milliseconds) OpenOCD should wait after asserting nSRST (active-low system reset) before allowing it to be deasserted. @end deffn -@deffn {Command} adapter_nsrst_delay milliseconds +@deffn {Command} adapter srst delay milliseconds How long (in milliseconds) OpenOCD should wait after deasserting nSRST (active-low system reset) before starting new JTAG operations. When a board has a reset button connected to SRST line it will @@ -4889,7 +4890,7 @@ the target clocks are fully set up.) before @command{reset-assert-pre} is called. This is the most robust place to use @command{jtag_rclk} -or @command{adapter_khz} to switch to a low JTAG clock rate, +or @command{adapter speed} to switch to a low JTAG clock rate, when reset disables PLLs needed to use a fast clock. @item @b{resume-start} @* Before any target is resumed @@ -10736,7 +10737,7 @@ To set the JTAG frequency use the command: @example # Example: 1.234MHz -adapter_khz 1234 +adapter speed 1234 @end example diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c index e2782a777..af75917a3 100644 --- a/src/jtag/adapter.c +++ b/src/jtag/adapter.c @@ -66,7 +66,7 @@ static int jim_adapter_name(Jim_Interp *interp, int argc, Jim_Obj * const *argv) return JIM_OK; } -COMMAND_HANDLER(interface_transport_command) +COMMAND_HANDLER(adapter_transports_command) { char **transports; int retval; @@ -85,12 +85,12 @@ COMMAND_HANDLER(interface_transport_command) return retval; } -COMMAND_HANDLER(handle_interface_list_command) +COMMAND_HANDLER(handle_adapter_list_command) { - if (strcmp(CMD_NAME, "interface_list") == 0 && CMD_ARGC > 0) + if (strcmp(CMD_NAME, "list") == 0 && CMD_ARGC > 0) return ERROR_COMMAND_SYNTAX_ERROR; - command_print(CMD, "The following debug interfaces are available:"); + command_print(CMD, "The following debug adapters are available:"); for (unsigned i = 0; NULL != adapter_drivers[i]; i++) { const char *name = adapter_drivers[i]->name; command_print(CMD, "%u: %s", i + 1, name); @@ -99,7 +99,7 @@ COMMAND_HANDLER(handle_interface_list_command) return ERROR_OK; } -COMMAND_HANDLER(handle_interface_command) +COMMAND_HANDLER(handle_adapter_driver_command) { int retval; @@ -134,7 +134,7 @@ COMMAND_HANDLER(handle_interface_command) */ LOG_ERROR("The specified debug interface was not found (%s)", CMD_ARGV[0]); - CALL_COMMAND_HANDLER(handle_interface_list_command); + CALL_COMMAND_HANDLER(handle_adapter_list_command); return ERROR_JTAG_INVALID_INTERFACE; } @@ -355,7 +355,7 @@ next: return ERROR_OK; } -COMMAND_HANDLER(handle_adapter_nsrst_delay_command) +COMMAND_HANDLER(handle_adapter_srst_delay_command) { if (CMD_ARGC > 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -365,11 +365,11 @@ COMMAND_HANDLER(handle_adapter_nsrst_delay_command) jtag_set_nsrst_delay(delay); } - command_print(CMD, "adapter_nsrst_delay: %u", jtag_get_nsrst_delay()); + command_print(CMD, "adapter srst delay: %u", jtag_get_nsrst_delay()); return ERROR_OK; } -COMMAND_HANDLER(handle_adapter_nsrst_assert_width_command) +COMMAND_HANDLER(handle_adapter_srst_pulse_width_command) { if (CMD_ARGC > 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -379,11 +379,11 @@ COMMAND_HANDLER(handle_adapter_nsrst_assert_width_command) jtag_set_nsrst_assert_width(width); } - command_print(CMD, "adapter_nsrst_assert_width: %u", jtag_get_nsrst_assert_width()); + command_print(CMD, "adapter srst pulse_width: %u", jtag_get_nsrst_assert_width()); return ERROR_OK; } -COMMAND_HANDLER(handle_adapter_khz_command) +COMMAND_HANDLER(handle_adapter_speed_command) { if (CMD_ARGC > 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -524,7 +524,70 @@ static const struct command_registration adapter_usb_command_handlers[] = { }; #endif /* MINIDRIVER */ +static const struct command_registration adapter_srst_command_handlers[] = { + { + .name = "delay", + .handler = handle_adapter_srst_delay_command, + .mode = COMMAND_ANY, + .help = "delay after deasserting SRST in ms", + .usage = "[milliseconds]", + }, + { + .name = "pulse_width", + .handler = handle_adapter_srst_pulse_width_command, + .mode = COMMAND_ANY, + .help = "SRST assertion pulse width in ms", + .usage = "[milliseconds]", + }, + COMMAND_REGISTRATION_DONE +}; + static const struct command_registration adapter_command_handlers[] = { + { + .name = "driver", + .handler = handle_adapter_driver_command, + .mode = COMMAND_CONFIG, + .help = "Select a debug adapter driver", + .usage = "driver_name", + }, + { + .name = "speed", + .handler = handle_adapter_speed_command, + .mode = COMMAND_ANY, + .help = "With an argument, change to the specified maximum " + "jtag speed. For JTAG, 0 KHz signifies adaptive " + "clocking. " + "With or without argument, display current setting.", + .usage = "[khz]", + }, + { + .name = "list", + .handler = handle_adapter_list_command, + .mode = COMMAND_ANY, + .help = "List all built-in debug adapter drivers", + .usage = "", + }, + { + .name = "name", + .mode = COMMAND_ANY, + .jim_handler = jim_adapter_name, + .help = "Returns the name of the currently " + "selected adapter (driver)", + }, + { + .name = "srst", + .mode = COMMAND_ANY, + .help = "srst adapter command group", + .usage = "", + .chain = adapter_srst_command_handlers, + }, + { + .name = "transports", + .handler = adapter_transports_command, + .mode = COMMAND_CONFIG, + .help = "Declare transports the adapter supports.", + .usage = "transport ... ", + }, #ifndef HAVE_JTAG_MINIDRIVER_H { .name = "usb", @@ -559,58 +622,6 @@ static const struct command_registration interface_command_handlers[] = { .usage = "", .chain = adapter_command_handlers, }, - { - .name = "adapter_khz", - .handler = handle_adapter_khz_command, - .mode = COMMAND_ANY, - .help = "With an argument, change to the specified maximum " - "jtag speed. For JTAG, 0 KHz signifies adaptive " - " clocking. " - "With or without argument, display current setting.", - .usage = "[khz]", - }, - { - .name = "adapter_name", - .mode = COMMAND_ANY, - .jim_handler = jim_adapter_name, - .help = "Returns the name of the currently " - "selected adapter (driver)", - }, - { - .name = "adapter_nsrst_delay", - .handler = handle_adapter_nsrst_delay_command, - .mode = COMMAND_ANY, - .help = "delay after deasserting SRST in ms", - .usage = "[milliseconds]", - }, - { - .name = "adapter_nsrst_assert_width", - .handler = handle_adapter_nsrst_assert_width_command, - .mode = COMMAND_ANY, - .help = "delay after asserting SRST in ms", - .usage = "[milliseconds]", - }, - { - .name = "interface", - .handler = handle_interface_command, - .mode = COMMAND_CONFIG, - .help = "Select a debug adapter interface (driver)", - .usage = "driver_name", - }, - { - .name = "interface_transports", - .handler = interface_transport_command, - .mode = COMMAND_CONFIG, - .help = "Declare transports the interface supports.", - .usage = "transport ... ", - }, - { - .name = "interface_list", - .handler = handle_interface_list_command, - .mode = COMMAND_ANY, - .help = "List all built-in debug adapter interfaces (drivers)", - .usage = "", - }, { .name = "reset_config", .handler = handle_reset_config_command, diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 355152136..440d8ea74 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -120,18 +120,18 @@ proc jtag_ntrst_assert_width args { # FIXME phase these aids out after about April 2011 # proc jtag_khz args { - echo "DEPRECATED! use 'adapter_khz' not 'jtag_khz'" - eval adapter_khz $args + echo "DEPRECATED! use 'adapter speed' not 'jtag_khz'" + eval adapter speed $args } proc jtag_nsrst_delay args { - echo "DEPRECATED! use 'adapter_nsrst_delay' not 'jtag_nsrst_delay'" - eval adapter_nsrst_delay $args + echo "DEPRECATED! use 'adapter srst delay' not 'jtag_nsrst_delay'" + eval adapter srst delay $args } proc jtag_nsrst_assert_width args { - echo "DEPRECATED! use 'adapter_nsrst_assert_width' not 'jtag_nsrst_assert_width'" - eval adapter_nsrst_assert_width $args + echo "DEPRECATED! use 'adapter srst pulse_width' not 'jtag_nsrst_assert_width'" + eval adapter srst pulse_width $args } proc jtag_reset args { @@ -176,4 +176,39 @@ proc stlink args { eval hla $args } +proc adapter_khz args { + echo "DEPRECATED! use 'adapter speed' not 'adapter_khz'" + eval adapter speed $args +} + +proc adapter_name args { + echo "DEPRECATED! use 'adapter name' not 'adapter_name'" + eval adapter name $args +} + +proc adapter_nsrst_delay args { + echo "DEPRECATED! use 'adapter srst delay' not 'adapter_nsrst_delay'" + eval adapter srst delay $args +} + +proc adapter_nsrst_assert_width args { + echo "DEPRECATED! use 'adapter srst pulse_width' not 'adapter_nsrst_assert_width'" + eval adapter srst pulse_width $args +} + +proc interface args { + echo "DEPRECATED! use 'adapter driver' not 'interface'" + eval adapter driver $args +} + +proc interface_transports args { + echo "DEPRECATED! use 'adapter transports' not 'interface_transports'" + eval adapter transports $args +} + +proc interface_list args { + echo "DEPRECATED! use 'adapter list' not 'interface_list'" + eval adapter list $args +} + # END MIGRATION AIDS From 70babcc00b5f495e4d0dbac9bad88d78592d2779 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Wed, 14 Aug 2019 13:17:51 +0200 Subject: [PATCH 107/354] move ftdi_location deprecation helper to proper place Change-Id: I927d4e918acbf321aea1dd7a8de95fbaa8fbbbf0 Signed-off-by: Oleksij Rempel Reviewed-on: http://openocd.zylin.com/5278 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/startup.tcl | 5 +++++ src/target/startup.tcl | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 440d8ea74..2ac857158 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -211,4 +211,9 @@ proc interface_list args { eval adapter list $args } +proc ftdi_location args { + echo "DEPRECATED! use 'adapter usb location' not 'ftdi_location'" + eval adapter usb location $args +} + # END MIGRATION AIDS diff --git a/src/target/startup.tcl b/src/target/startup.tcl index 4d4426f98..cf844e1f6 100644 --- a/src/target/startup.tcl +++ b/src/target/startup.tcl @@ -221,9 +221,3 @@ proc cortex_a8 args { echo "DEPRECATED! use 'cortex_a' not 'cortex_a8'" eval cortex_a $args } - -# deprecated ftdi cmds -proc ftdi_location args { - echo "DEPRECATED! use 'adapter usb location' not 'ftdi_location'" - eval adapter usb location $args -} From 291d1511aab3eee6a181510e1b1ff9282d47e69c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 23 Aug 2019 15:12:57 +0200 Subject: [PATCH 108/354] openocd: fix minor inconsistencies after renaming "adapter" command Replace in the code any reference to the deprecated commands. Change-Id: I75d28064017d664990b4024967900f32e196230a Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5282 Tested-by: jenkins Reviewed-by: Marc Schink Reviewed-by: Oleksij Rempel --- src/jtag/core.c | 6 +++--- src/jtag/drivers/cmsis_dap_usb.c | 4 ++-- src/svf/svf.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index 111b122d9..24d645a49 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1519,9 +1519,9 @@ int adapter_init(struct command_context *cmd_ctx) return ERROR_OK; if (!adapter_driver) { - /* nothing was previously specified by "interface" command */ + /* nothing was previously specified by "adapter driver" command */ LOG_ERROR("Debug Adapter has to be specified, " - "see \"interface\" command"); + "see \"adapter driver\" command"); return ERROR_JTAG_INVALID_INTERFACE; } @@ -1538,7 +1538,7 @@ int adapter_init(struct command_context *cmd_ctx) if (CLOCK_MODE_UNSELECTED == clock_mode) { LOG_ERROR("An adapter speed is not selected in the init script." - " Insert a call to adapter_khz or jtag_rclk to proceed."); + " Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed."); return ERROR_JTAG_INIT_FAILED; } diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c index c0728214c..3d2693c0a 100644 --- a/src/jtag/drivers/cmsis_dap_usb.c +++ b/src/jtag/drivers/cmsis_dap_usb.c @@ -1628,10 +1628,10 @@ static int cmsis_dap_execute_queue(void) static int cmsis_dap_speed(int speed) { if (speed > DAP_MAX_CLOCK) - LOG_INFO("High speed (adapter_khz %d) may be limited by adapter firmware.", speed); + LOG_INFO("High speed (adapter speed %d) may be limited by adapter firmware.", speed); if (speed == 0) { - LOG_ERROR("RTCK not supported. Set nonzero adapter_khz."); + LOG_ERROR("RTCK not supported. Set nonzero \"adapter speed\"."); return ERROR_JTAG_NOT_IMPLEMENTED; } diff --git a/src/svf/svf.c b/src/svf/svf.c index 759ba5263..5d87c8944 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -990,7 +990,7 @@ static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str) /* TODO: set jtag speed to */ if (svf_para.frequency > 0) { command_run_linef(cmd_ctx, - "adapter_khz %d", + "adapter speed %d", (int)svf_para.frequency / 1000); LOG_DEBUG("\tfrequency = %f", svf_para.frequency); } From 2aa2ed1d8a3c489b0b7c1590e91f9989f2c42fb6 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 23 Aug 2019 15:49:58 +0200 Subject: [PATCH 109/354] tcl: replace command "interface" with "adapter driver" Avoid annoying "deprecated" messages while running the scripts distributed with OpenOCD code. Change automatically created with command sed -i 's/^interface /adapter driver /' $(find tcl/ -type f) Change-Id: I2291dfb96e164beecbeb3366ce83f9df2ad6c197 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5283 Reviewed-by: Marc Schink Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/board/altera_sockit.cfg | 2 +- tcl/board/digilent_analog_discovery.cfg | 2 +- tcl/board/gumstix-aerocore.cfg | 2 +- tcl/board/kasli.cfg | 2 +- tcl/board/novena-internal-fpga.cfg | 2 +- tcl/board/numato_mimas_a7.cfg | 2 +- tcl/board/quark_d2000_refboard.cfg | 2 +- tcl/board/sayma_amc.cfg | 2 +- tcl/board/sifive-hifive1.cfg | 2 +- tcl/interface/altera-usb-blaster.cfg | 2 +- tcl/interface/altera-usb-blaster2.cfg | 2 +- tcl/interface/arm-jtag-ew.cfg | 2 +- tcl/interface/at91rm9200.cfg | 2 +- tcl/interface/buspirate.cfg | 2 +- tcl/interface/chameleon.cfg | 2 +- tcl/interface/cmsis-dap.cfg | 2 +- tcl/interface/dummy.cfg | 2 +- tcl/interface/estick.cfg | 2 +- tcl/interface/flashlink.cfg | 2 +- tcl/interface/ft232r.cfg | 2 +- tcl/interface/ftdi/100ask-openjtag.cfg | 2 +- tcl/interface/ftdi/axm0432.cfg | 2 +- tcl/interface/ftdi/c232hm.cfg | 2 +- tcl/interface/ftdi/calao-usb-a9260-c01.cfg | 2 +- tcl/interface/ftdi/calao-usb-a9260-c02.cfg | 2 +- tcl/interface/ftdi/cortino.cfg | 2 +- tcl/interface/ftdi/digilent-hs1.cfg | 2 +- tcl/interface/ftdi/digilent-hs2.cfg | 2 +- tcl/interface/ftdi/digilent_jtag_hs3.cfg | 2 +- tcl/interface/ftdi/digilent_jtag_smt2.cfg | 2 +- tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg | 2 +- tcl/interface/ftdi/dlp-usb1232h.cfg | 2 +- tcl/interface/ftdi/dp_busblaster.cfg | 2 +- tcl/interface/ftdi/dp_busblaster_kt-link.cfg | 2 +- tcl/interface/ftdi/flossjtag-noeeprom.cfg | 2 +- tcl/interface/ftdi/flossjtag.cfg | 2 +- tcl/interface/ftdi/flyswatter.cfg | 2 +- tcl/interface/ftdi/flyswatter2.cfg | 2 +- tcl/interface/ftdi/ft232h-module-swd.cfg | 2 +- tcl/interface/ftdi/gw16042.cfg | 2 +- tcl/interface/ftdi/hilscher_nxhx10_etm.cfg | 2 +- tcl/interface/ftdi/hilscher_nxhx500_etm.cfg | 2 +- tcl/interface/ftdi/hilscher_nxhx500_re.cfg | 2 +- tcl/interface/ftdi/hilscher_nxhx50_etm.cfg | 2 +- tcl/interface/ftdi/hilscher_nxhx50_re.cfg | 2 +- tcl/interface/ftdi/hitex_lpc1768stick.cfg | 2 +- tcl/interface/ftdi/hitex_str9-comstick.cfg | 2 +- tcl/interface/ftdi/icebear.cfg | 2 +- tcl/interface/ftdi/incircuit-icprog.cfg | 2 +- tcl/interface/ftdi/iotlab-usb.cfg | 2 +- tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg | 2 +- tcl/interface/ftdi/jtagkey.cfg | 2 +- tcl/interface/ftdi/jtagkey2.cfg | 2 +- tcl/interface/ftdi/jtagkey2p.cfg | 2 +- tcl/interface/ftdi/kt-link.cfg | 2 +- tcl/interface/ftdi/lisa-l.cfg | 2 +- tcl/interface/ftdi/luminary-icdi.cfg | 2 +- tcl/interface/ftdi/luminary-lm3s811.cfg | 2 +- tcl/interface/ftdi/luminary.cfg | 2 +- tcl/interface/ftdi/m53evk.cfg | 2 +- tcl/interface/ftdi/mbftdi.cfg | 2 +- tcl/interface/ftdi/minimodule-swd.cfg | 2 +- tcl/interface/ftdi/minimodule.cfg | 2 +- tcl/interface/ftdi/minispartan6.cfg | 2 +- tcl/interface/ftdi/neodb.cfg | 2 +- tcl/interface/ftdi/ngxtech.cfg | 2 +- tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg | 2 +- tcl/interface/ftdi/olimex-arm-usb-ocd.cfg | 2 +- tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg | 2 +- tcl/interface/ftdi/olimex-jtag-tiny.cfg | 2 +- tcl/interface/ftdi/oocdlink.cfg | 2 +- tcl/interface/ftdi/opendous_ftdi.cfg | 2 +- tcl/interface/ftdi/openocd-usb-hs.cfg | 2 +- tcl/interface/ftdi/openocd-usb.cfg | 2 +- tcl/interface/ftdi/openrd.cfg | 2 +- tcl/interface/ftdi/pipistrello.cfg | 2 +- tcl/interface/ftdi/redbee-econotag.cfg | 2 +- tcl/interface/ftdi/redbee-usb.cfg | 2 +- tcl/interface/ftdi/sheevaplug.cfg | 2 +- tcl/interface/ftdi/signalyzer-lite.cfg | 2 +- tcl/interface/ftdi/signalyzer.cfg | 2 +- tcl/interface/ftdi/stm32-stick.cfg | 2 +- tcl/interface/ftdi/ti-icdi.cfg | 2 +- tcl/interface/ftdi/tumpa-lite.cfg | 2 +- tcl/interface/ftdi/tumpa.cfg | 2 +- tcl/interface/ftdi/turtelizer2-revB.cfg | 2 +- tcl/interface/ftdi/turtelizer2-revC.cfg | 2 +- tcl/interface/ftdi/um232h.cfg | 2 +- tcl/interface/ftdi/vpaclink.cfg | 2 +- tcl/interface/ftdi/xds100v2.cfg | 2 +- tcl/interface/imx-native.cfg | 2 +- tcl/interface/jlink.cfg | 2 +- tcl/interface/jtag_vpi.cfg | 2 +- tcl/interface/kitprog.cfg | 2 +- tcl/interface/nds32-aice.cfg | 2 +- tcl/interface/opendous.cfg | 2 +- tcl/interface/openjtag.cfg | 2 +- tcl/interface/osbdm.cfg | 2 +- tcl/interface/parport.cfg | 2 +- tcl/interface/parport_dlc5.cfg | 2 +- tcl/interface/raspberrypi-native.cfg | 2 +- tcl/interface/raspberrypi2-native.cfg | 2 +- tcl/interface/rlink.cfg | 2 +- tcl/interface/stlink.cfg | 2 +- tcl/interface/sysfsgpio-raspberrypi.cfg | 2 +- tcl/interface/ti-icdi.cfg | 2 +- tcl/interface/ulink.cfg | 2 +- tcl/interface/usb-jtag.cfg | 2 +- tcl/interface/usbprog.cfg | 2 +- tcl/interface/vsllink.cfg | 2 +- tcl/interface/xds110.cfg | 2 +- 111 files changed, 111 insertions(+), 111 deletions(-) diff --git a/tcl/board/altera_sockit.cfg b/tcl/board/altera_sockit.cfg index 569414331..1466bd46b 100644 --- a/tcl/board/altera_sockit.cfg +++ b/tcl/board/altera_sockit.cfg @@ -7,7 +7,7 @@ # openocd does not currently support the on-board USB Blaster II. # Install the JTAG header and use a USB Blaster instead. -interface usb_blaster +adapter driver usb_blaster source [find target/altera_fpgasoc.cfg] diff --git a/tcl/board/digilent_analog_discovery.cfg b/tcl/board/digilent_analog_discovery.cfg index d356fc0f4..65eb66084 100644 --- a/tcl/board/digilent_analog_discovery.cfg +++ b/tcl/board/digilent_analog_discovery.cfg @@ -7,7 +7,7 @@ # https://github.com/bvanheu/urjtag-ad/commit/8bd883ee01d134f94b79cbbd00df42cd03bafd71 # -interface ftdi +adapter driver ftdi ftdi_device_desc "Digilent USB Device" ftdi_vid_pid 0x0403 0x6014 diff --git a/tcl/board/gumstix-aerocore.cfg b/tcl/board/gumstix-aerocore.cfg index ba217c043..f0103ed45 100644 --- a/tcl/board/gumstix-aerocore.cfg +++ b/tcl/board/gumstix-aerocore.cfg @@ -1,6 +1,6 @@ # JTAG for the STM32F4x chip used on the Gumstix AeroCore is available on # the first interface of a Quad FTDI chip. nTRST is bit 4. -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6011 ftdi_layout_init 0x0000 0x001b diff --git a/tcl/board/kasli.cfg b/tcl/board/kasli.cfg index 2c5e26853..fb59f931f 100644 --- a/tcl/board/kasli.cfg +++ b/tcl/board/kasli.cfg @@ -1,4 +1,4 @@ -interface ftdi +adapter driver ftdi ftdi_device_desc "Quad RS232-HS" ftdi_vid_pid 0x0403 0x6011 ftdi_channel 0 diff --git a/tcl/board/novena-internal-fpga.cfg b/tcl/board/novena-internal-fpga.cfg index 87495e372..24a76dceb 100644 --- a/tcl/board/novena-internal-fpga.cfg +++ b/tcl/board/novena-internal-fpga.cfg @@ -14,7 +14,7 @@ # | DISP0_DAT17 | FPGA_TMS | 5-11 | 139 | TMS | # +-------------+--------------+------+-------+---------+ -interface sysfsgpio +adapter driver sysfsgpio transport select jtag diff --git a/tcl/board/numato_mimas_a7.cfg b/tcl/board/numato_mimas_a7.cfg index 1261feacc..a538872d1 100644 --- a/tcl/board/numato_mimas_a7.cfg +++ b/tcl/board/numato_mimas_a7.cfg @@ -7,7 +7,7 @@ # Programming while powering via USB may lead to programming failure. # Therefore, prefer external power supply. -interface ftdi +adapter driver ftdi ftdi_device_desc "Mimas Artix 7 FPGA Module" ftdi_vid_pid 0x2a19 0x1009 diff --git a/tcl/board/quark_d2000_refboard.cfg b/tcl/board/quark_d2000_refboard.cfg index d1388bbaa..460e8c969 100644 --- a/tcl/board/quark_d2000_refboard.cfg +++ b/tcl/board/quark_d2000_refboard.cfg @@ -1,7 +1,7 @@ # Intel Quark microcontroller D2000 Reference Board (web search for doc num 333582) # the board has an onboard FTDI FT232H chip -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6014 ftdi_channel 0 diff --git a/tcl/board/sayma_amc.cfg b/tcl/board/sayma_amc.cfg index 5d338ed8a..0b507ee0e 100644 --- a/tcl/board/sayma_amc.cfg +++ b/tcl/board/sayma_amc.cfg @@ -10,7 +10,7 @@ # Sayma AMC is usually combined with Sayma RTM (rear transition module) # which features an Artix 7 FPGA. -interface ftdi +adapter driver ftdi ftdi_device_desc "Quad RS232-HS" ftdi_vid_pid 0x0403 0x6011 ftdi_channel 0 diff --git a/tcl/board/sifive-hifive1.cfg b/tcl/board/sifive-hifive1.cfg index 9bc66701c..9e62bbd04 100644 --- a/tcl/board/sifive-hifive1.cfg +++ b/tcl/board/sifive-hifive1.cfg @@ -1,6 +1,6 @@ adapter_khz 10000 -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/altera-usb-blaster.cfg b/tcl/interface/altera-usb-blaster.cfg index 1bfef9dc4..84e77b13c 100644 --- a/tcl/interface/altera-usb-blaster.cfg +++ b/tcl/interface/altera-usb-blaster.cfg @@ -4,7 +4,7 @@ # http://www.altera.com/literature/ug/ug_usb_blstr.pdf # -interface usb_blaster +adapter driver usb_blaster usb_blaster_lowlevel_driver ftdi # These are already the defaults. # usb_blaster_vid_pid 0x09FB 0x6001 diff --git a/tcl/interface/altera-usb-blaster2.cfg b/tcl/interface/altera-usb-blaster2.cfg index c35be1970..4642b1dcf 100644 --- a/tcl/interface/altera-usb-blaster2.cfg +++ b/tcl/interface/altera-usb-blaster2.cfg @@ -2,7 +2,7 @@ # Altera USB-Blaster II # -interface usb_blaster +adapter driver usb_blaster usb_blaster_vid_pid 0x09fb 0x6010 0x09fb 0x6810 usb_blaster_lowlevel_driver ublast2 usb_blaster_firmware /path/to/quartus/blaster_6810.hex diff --git a/tcl/interface/arm-jtag-ew.cfg b/tcl/interface/arm-jtag-ew.cfg index 2e8b57e4c..250592f20 100644 --- a/tcl/interface/arm-jtag-ew.cfg +++ b/tcl/interface/arm-jtag-ew.cfg @@ -4,5 +4,5 @@ # http://www.olimex.com/dev/arm-jtag-ew.html # -interface arm-jtag-ew +adapter driver arm-jtag-ew diff --git a/tcl/interface/at91rm9200.cfg b/tcl/interface/at91rm9200.cfg index 20826478d..0561dac43 100644 --- a/tcl/interface/at91rm9200.cfg +++ b/tcl/interface/at91rm9200.cfg @@ -4,6 +4,6 @@ # TODO: URL? # -interface at91rm9200 +adapter driver at91rm9200 at91rm9200_device rea_ecr diff --git a/tcl/interface/buspirate.cfg b/tcl/interface/buspirate.cfg index c2f3a83c4..b02d29d06 100644 --- a/tcl/interface/buspirate.cfg +++ b/tcl/interface/buspirate.cfg @@ -4,7 +4,7 @@ # http://dangerousprototypes.com/bus-pirate-manual/ # -interface buspirate +adapter driver buspirate # you need to specify port on which BP lives #buspirate_port /dev/ttyUSB0 diff --git a/tcl/interface/chameleon.cfg b/tcl/interface/chameleon.cfg index 2fb74681c..f523ee73e 100644 --- a/tcl/interface/chameleon.cfg +++ b/tcl/interface/chameleon.cfg @@ -4,6 +4,6 @@ # http://www.amontec.com/chameleon.shtml # -interface parport +adapter driver parport parport_cable chameleon diff --git a/tcl/interface/cmsis-dap.cfg b/tcl/interface/cmsis-dap.cfg index ab5c187eb..887d2d713 100644 --- a/tcl/interface/cmsis-dap.cfg +++ b/tcl/interface/cmsis-dap.cfg @@ -4,7 +4,7 @@ # http://www.keil.com/support/man/docs/dapdebug/ # -interface cmsis-dap +adapter driver cmsis-dap # Optionally specify the serial number of CMSIS-DAP usb device. #cmsis_dap_serial 02200201E6661E601B98E3B9 diff --git a/tcl/interface/dummy.cfg b/tcl/interface/dummy.cfg index 1c148c0cb..6c2fe5f2f 100644 --- a/tcl/interface/dummy.cfg +++ b/tcl/interface/dummy.cfg @@ -2,5 +2,5 @@ # Dummy interface (for testing purposes) # -interface dummy +adapter driver dummy diff --git a/tcl/interface/estick.cfg b/tcl/interface/estick.cfg index adefcb73f..75e6ea8e5 100644 --- a/tcl/interface/estick.cfg +++ b/tcl/interface/estick.cfg @@ -4,4 +4,4 @@ # http://code.google.com/p/estick-jtag/ # -interface opendous +adapter driver opendous diff --git a/tcl/interface/flashlink.cfg b/tcl/interface/flashlink.cfg index 56dc35e20..e0a4b97d0 100644 --- a/tcl/interface/flashlink.cfg +++ b/tcl/interface/flashlink.cfg @@ -11,6 +11,6 @@ if { [info exists PARPORTADDR] } { set _PARPORTADDR 0 } -interface parport +adapter driver parport parport_port $_PARPORTADDR parport_cable flashlink diff --git a/tcl/interface/ft232r.cfg b/tcl/interface/ft232r.cfg index b4f71c8d4..24e338ff3 100644 --- a/tcl/interface/ft232r.cfg +++ b/tcl/interface/ft232r.cfg @@ -1,2 +1,2 @@ -interface ft232r +adapter driver ft232r adapter_khz 1000 diff --git a/tcl/interface/ftdi/100ask-openjtag.cfg b/tcl/interface/ftdi/100ask-openjtag.cfg index 01ae2f7ea..3cbd37e06 100644 --- a/tcl/interface/ftdi/100ask-openjtag.cfg +++ b/tcl/interface/ftdi/100ask-openjtag.cfg @@ -7,7 +7,7 @@ # https://blog.matthiasbock.net/wp-content/uploads/2015/04/100ask-JTAGv3.pdf # -interface ftdi +adapter driver ftdi ftdi_device_desc "USB<=>JTAG&RS232" ftdi_vid_pid 0x1457 0x5118 diff --git a/tcl/interface/ftdi/axm0432.cfg b/tcl/interface/ftdi/axm0432.cfg index 0c24a333e..6cc1752e2 100644 --- a/tcl/interface/ftdi/axm0432.cfg +++ b/tcl/interface/ftdi/axm0432.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "Symphony SoundBite" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/c232hm.cfg b/tcl/interface/ftdi/c232hm.cfg index 4f623e0f8..27cf76674 100644 --- a/tcl/interface/ftdi/c232hm.cfg +++ b/tcl/interface/ftdi/c232hm.cfg @@ -13,7 +13,7 @@ # http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf # http://www.ftdichip.com/Support/Documents/AppNotes/AN_129_FTDI_Hi_Speed_USB_To_JTAG_Example.pdf -interface ftdi +adapter driver ftdi #ftdi_device_desc "C232HM-DDHSL-0" #ftdi_device_desc "C232HM-EDHSL-0" diff --git a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg b/tcl/interface/ftdi/calao-usb-a9260-c01.cfg index d3da6b7ec..a23ddbfb5 100644 --- a/tcl/interface/ftdi/calao-usb-a9260-c01.cfg +++ b/tcl/interface/ftdi/calao-usb-a9260-c01.cfg @@ -10,7 +10,7 @@ echo "interface uses the same layout as configs that were verified. Please repor echo "experience with this file to openocd-devel mailing list, so it could be marked" echo "as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "USB-A9260" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg b/tcl/interface/ftdi/calao-usb-a9260-c02.cfg index dc4dca8f7..67427c5c0 100644 --- a/tcl/interface/ftdi/calao-usb-a9260-c02.cfg +++ b/tcl/interface/ftdi/calao-usb-a9260-c02.cfg @@ -10,7 +10,7 @@ echo "interface uses the same layout as configs that were verified. Please repor echo "experience with this file to openocd-devel mailing list, so it could be marked" echo "as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "USB-A9260" ftdi_vid_pid 0x0403 0x6001 diff --git a/tcl/interface/ftdi/cortino.cfg b/tcl/interface/ftdi/cortino.cfg index 16ede6129..2bc516cc6 100644 --- a/tcl/interface/ftdi/cortino.cfg +++ b/tcl/interface/ftdi/cortino.cfg @@ -4,7 +4,7 @@ # http://www.hitex.com/index.php?id=cortino # -interface ftdi +adapter driver ftdi ftdi_device_desc "Cortino" ftdi_vid_pid 0x0640 0x0032 diff --git a/tcl/interface/ftdi/digilent-hs1.cfg b/tcl/interface/ftdi/digilent-hs1.cfg index e27249b3b..dfba3393a 100644 --- a/tcl/interface/ftdi/digilent-hs1.cfg +++ b/tcl/interface/ftdi/digilent-hs1.cfg @@ -1,7 +1,7 @@ # this supports JTAG-HS1 and JTAG-SMT1 # (the later being the OEM on-board version) -interface ftdi +adapter driver ftdi ftdi_device_desc "Digilent Adept USB Device" ftdi_vid_pid 0x0403 0x6010 # channel 1 does not have any functionality diff --git a/tcl/interface/ftdi/digilent-hs2.cfg b/tcl/interface/ftdi/digilent-hs2.cfg index 2005b66af..ae6ba01bb 100644 --- a/tcl/interface/ftdi/digilent-hs2.cfg +++ b/tcl/interface/ftdi/digilent-hs2.cfg @@ -1,6 +1,6 @@ # this supports JTAG-HS2 (and apparently Nexys4 as well) -interface ftdi +adapter driver ftdi ftdi_device_desc "Digilent Adept USB Device" ftdi_vid_pid 0x0403 0x6014 diff --git a/tcl/interface/ftdi/digilent_jtag_hs3.cfg b/tcl/interface/ftdi/digilent_jtag_hs3.cfg index f7b8e570c..7160bed8e 100644 --- a/tcl/interface/ftdi/digilent_jtag_hs3.cfg +++ b/tcl/interface/ftdi/digilent_jtag_hs3.cfg @@ -2,7 +2,7 @@ # Digilent JTAG-HS3 # -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6014 ftdi_device_desc "Digilent USB Device" diff --git a/tcl/interface/ftdi/digilent_jtag_smt2.cfg b/tcl/interface/ftdi/digilent_jtag_smt2.cfg index 014fe1475..493ed6af5 100644 --- a/tcl/interface/ftdi/digilent_jtag_smt2.cfg +++ b/tcl/interface/ftdi/digilent_jtag_smt2.cfg @@ -7,7 +7,7 @@ # http://electronix.ru/forum/index.php?showtopic=114633&view=findpost&p=1215497 and ZedBoard schematics # -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6014 ftdi_layout_init 0x2088 0x3f8b diff --git a/tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg b/tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg index a83a0081e..bc783a46c 100644 --- a/tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg +++ b/tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg @@ -10,7 +10,7 @@ # Note that the digilent_jtag_smt2 layout does not work and hangs while # the ftdi_device_desc from digilent_hs2 is wrong. -interface ftdi +adapter driver ftdi ftdi_device_desc "Digilent USB Device" ftdi_vid_pid 0x0403 0x6014 ftdi_channel 0 diff --git a/tcl/interface/ftdi/dlp-usb1232h.cfg b/tcl/interface/ftdi/dlp-usb1232h.cfg index f447771e3..9ddc2c80a 100644 --- a/tcl/interface/ftdi/dlp-usb1232h.cfg +++ b/tcl/interface/ftdi/dlp-usb1232h.cfg @@ -12,7 +12,7 @@ echo "This file was not tested with real interface, it is based on schematics an echo "in ft2232.c. Please report your experience with this file to openocd-devel" echo "mailing list, so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/dp_busblaster.cfg b/tcl/interface/ftdi/dp_busblaster.cfg index 73827cfb8..86ab4d840 100644 --- a/tcl/interface/ftdi/dp_busblaster.cfg +++ b/tcl/interface/ftdi/dp_busblaster.cfg @@ -11,7 +11,7 @@ echo "Info : If you need SWD support, flash KT-Link buffer from https://github.com/bharrisau/busblaster and use dp_busblaster_kt-link.cfg instead" -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/dp_busblaster_kt-link.cfg b/tcl/interface/ftdi/dp_busblaster_kt-link.cfg index 2d27519d4..d49a4c98f 100644 --- a/tcl/interface/ftdi/dp_busblaster_kt-link.cfg +++ b/tcl/interface/ftdi/dp_busblaster_kt-link.cfg @@ -9,7 +9,7 @@ # http://dangerousprototypes.com/docs/Bus_Blaster # -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/flossjtag-noeeprom.cfg b/tcl/interface/ftdi/flossjtag-noeeprom.cfg index 18046e742..42ed18ec3 100644 --- a/tcl/interface/ftdi/flossjtag-noeeprom.cfg +++ b/tcl/interface/ftdi/flossjtag-noeeprom.cfg @@ -17,7 +17,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/flossjtag.cfg b/tcl/interface/ftdi/flossjtag.cfg index 13e1f0bb7..c4ad81dcc 100644 --- a/tcl/interface/ftdi/flossjtag.cfg +++ b/tcl/interface/ftdi/flossjtag.cfg @@ -17,7 +17,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6010 ftdi_device_desc "FLOSS-JTAG" #ftdi_serial "FJ000001" diff --git a/tcl/interface/ftdi/flyswatter.cfg b/tcl/interface/ftdi/flyswatter.cfg index 56dab1f33..5e9d4816d 100644 --- a/tcl/interface/ftdi/flyswatter.cfg +++ b/tcl/interface/ftdi/flyswatter.cfg @@ -4,7 +4,7 @@ # http://www.tincantools.com/product.php?productid=16134 # -interface ftdi +adapter driver ftdi ftdi_device_desc "Flyswatter" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/flyswatter2.cfg b/tcl/interface/ftdi/flyswatter2.cfg index 8bd4db4b7..45dd0bacb 100644 --- a/tcl/interface/ftdi/flyswatter2.cfg +++ b/tcl/interface/ftdi/flyswatter2.cfg @@ -4,7 +4,7 @@ # http://www.tincantools.com/product.php?productid=16153 # -interface ftdi +adapter driver ftdi ftdi_device_desc "Flyswatter2" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/ft232h-module-swd.cfg b/tcl/interface/ftdi/ft232h-module-swd.cfg index d2bd1da61..e85640bc6 100644 --- a/tcl/interface/ftdi/ft232h-module-swd.cfg +++ b/tcl/interface/ftdi/ft232h-module-swd.cfg @@ -6,7 +6,7 @@ # # -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6014 diff --git a/tcl/interface/ftdi/gw16042.cfg b/tcl/interface/ftdi/gw16042.cfg index 90c6f7c12..1288f77b1 100644 --- a/tcl/interface/ftdi/gw16042.cfg +++ b/tcl/interface/ftdi/gw16042.cfg @@ -17,7 +17,7 @@ # BDBUS1 TXD (input) # -interface ftdi +adapter driver ftdi ftdi_device_desc "USB-JTAG" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg b/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg index b682333ed..3802f6d2c 100644 --- a/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "NXHX 10-ETM" ftdi_vid_pid 0x0640 0x0028 diff --git a/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg b/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg index 3483030c6..f2e64b4f5 100644 --- a/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "NXHX 500-ETM" ftdi_vid_pid 0x0640 0x0028 diff --git a/tcl/interface/ftdi/hilscher_nxhx500_re.cfg b/tcl/interface/ftdi/hilscher_nxhx500_re.cfg index b4cada055..38f3c690e 100644 --- a/tcl/interface/ftdi/hilscher_nxhx500_re.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx500_re.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "NXHX 500-RE" ftdi_vid_pid 0x0640 0x0028 diff --git a/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg b/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg index 67074a263..bff081f18 100644 --- a/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "NXHX 50-ETM" ftdi_vid_pid 0x0640 0x0028 diff --git a/tcl/interface/ftdi/hilscher_nxhx50_re.cfg b/tcl/interface/ftdi/hilscher_nxhx50_re.cfg index 966dcd812..f9fbd015a 100644 --- a/tcl/interface/ftdi/hilscher_nxhx50_re.cfg +++ b/tcl/interface/ftdi/hilscher_nxhx50_re.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "NXHX50-RE" ftdi_vid_pid 0x0640 0x0028 diff --git a/tcl/interface/ftdi/hitex_lpc1768stick.cfg b/tcl/interface/ftdi/hitex_lpc1768stick.cfg index f22d4f7b2..3f49522da 100644 --- a/tcl/interface/ftdi/hitex_lpc1768stick.cfg +++ b/tcl/interface/ftdi/hitex_lpc1768stick.cfg @@ -5,7 +5,7 @@ # -interface ftdi +adapter driver ftdi ftdi_device_desc "LPC1768-Stick" ftdi_vid_pid 0x0640 0x0026 diff --git a/tcl/interface/ftdi/hitex_str9-comstick.cfg b/tcl/interface/ftdi/hitex_str9-comstick.cfg index c46f0322c..2b3dc3690 100644 --- a/tcl/interface/ftdi/hitex_str9-comstick.cfg +++ b/tcl/interface/ftdi/hitex_str9-comstick.cfg @@ -4,7 +4,7 @@ # http://www.hitex.com/index.php?id=383 # -interface ftdi +adapter driver ftdi ftdi_device_desc "STR9-comStick" ftdi_vid_pid 0x0640 0x002c diff --git a/tcl/interface/ftdi/icebear.cfg b/tcl/interface/ftdi/icebear.cfg index 2c03d417b..04c27319e 100644 --- a/tcl/interface/ftdi/icebear.cfg +++ b/tcl/interface/ftdi/icebear.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "ICEbear JTAG adapter" ftdi_vid_pid 0x0403 0xc140 diff --git a/tcl/interface/ftdi/incircuit-icprog.cfg b/tcl/interface/ftdi/incircuit-icprog.cfg index 5e90a7035..e0bd5ef59 100644 --- a/tcl/interface/ftdi/incircuit-icprog.cfg +++ b/tcl/interface/ftdi/incircuit-icprog.cfg @@ -6,7 +6,7 @@ # http://wiki.in-circuit.de/images/0/06/610000158A_openocd.pdf # -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6010 ftdi_layout_init 0x0508 0x0f1b diff --git a/tcl/interface/ftdi/iotlab-usb.cfg b/tcl/interface/ftdi/iotlab-usb.cfg index fbbad0c86..caa0596fd 100644 --- a/tcl/interface/ftdi/iotlab-usb.cfg +++ b/tcl/interface/ftdi/iotlab-usb.cfg @@ -3,7 +3,7 @@ # https://github.com/iot-lab/iot-lab/wiki # -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6010 ftdi_layout_init 0x0008 0x000b diff --git a/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg b/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg index c5e5db420..82eeaa7b5 100644 --- a/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg +++ b/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg @@ -4,7 +4,7 @@ # http://www.distortec.com # -interface ftdi +adapter driver ftdi ftdi_device_desc "JTAG-lock-pick Tiny 2" ftdi_vid_pid 0x0403 0x8220 diff --git a/tcl/interface/ftdi/jtagkey.cfg b/tcl/interface/ftdi/jtagkey.cfg index 7b87e6df1..06463ab91 100644 --- a/tcl/interface/ftdi/jtagkey.cfg +++ b/tcl/interface/ftdi/jtagkey.cfg @@ -4,7 +4,7 @@ # http://www.amontec.com/jtagkey.shtml # -interface ftdi +adapter driver ftdi ftdi_device_desc "Amontec JTAGkey" ftdi_vid_pid 0x0403 0xcff8 diff --git a/tcl/interface/ftdi/jtagkey2.cfg b/tcl/interface/ftdi/jtagkey2.cfg index c6c2b32f4..ba151d3b5 100644 --- a/tcl/interface/ftdi/jtagkey2.cfg +++ b/tcl/interface/ftdi/jtagkey2.cfg @@ -4,7 +4,7 @@ # http://www.amontec.com/jtagkey2.shtml # -interface ftdi +adapter driver ftdi ftdi_device_desc "Amontec JTAGkey-2" ftdi_vid_pid 0x0403 0xcff8 diff --git a/tcl/interface/ftdi/jtagkey2p.cfg b/tcl/interface/ftdi/jtagkey2p.cfg index dc9c4565e..acb5047e9 100644 --- a/tcl/interface/ftdi/jtagkey2p.cfg +++ b/tcl/interface/ftdi/jtagkey2p.cfg @@ -4,7 +4,7 @@ # http://www.amontec.com/jtagkey2p.shtml # -interface ftdi +adapter driver ftdi ftdi_device_desc "Amontec JTAGkey-2P" ftdi_vid_pid 0x0403 0xcff8 diff --git a/tcl/interface/ftdi/kt-link.cfg b/tcl/interface/ftdi/kt-link.cfg index 1f28d3a10..5fc5db9d0 100644 --- a/tcl/interface/ftdi/kt-link.cfg +++ b/tcl/interface/ftdi/kt-link.cfg @@ -4,7 +4,7 @@ # http://www.kristech.eu # -interface ftdi +adapter driver ftdi ftdi_device_desc "KT-LINK" ftdi_vid_pid 0x0403 0xbbe2 diff --git a/tcl/interface/ftdi/lisa-l.cfg b/tcl/interface/ftdi/lisa-l.cfg index 67002bb96..4e52f7b7e 100644 --- a/tcl/interface/ftdi/lisa-l.cfg +++ b/tcl/interface/ftdi/lisa-l.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on schematics an echo "in ft2232.c. Please report your experience with this file to openocd-devel" echo "mailing list, so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "Lisa/L" ftdi_vid_pid 0x0403 0x6010 ftdi_channel 1 diff --git a/tcl/interface/ftdi/luminary-icdi.cfg b/tcl/interface/ftdi/luminary-icdi.cfg index 2eea806d6..8bc783e92 100644 --- a/tcl/interface/ftdi/luminary-icdi.cfg +++ b/tcl/interface/ftdi/luminary-icdi.cfg @@ -15,7 +15,7 @@ # http://www.luminarymicro.com/products/ek-lm3s9b92.html # -interface ftdi +adapter driver ftdi ftdi_device_desc "Luminary Micro ICDI Board" ftdi_vid_pid 0x0403 0xbcda diff --git a/tcl/interface/ftdi/luminary-lm3s811.cfg b/tcl/interface/ftdi/luminary-lm3s811.cfg index 543b1e08f..aac915e34 100644 --- a/tcl/interface/ftdi/luminary-lm3s811.cfg +++ b/tcl/interface/ftdi/luminary-lm3s811.cfg @@ -11,7 +11,7 @@ # need to use the "luminary_icdi" layout to work correctly. # -interface ftdi +adapter driver ftdi ftdi_device_desc "LM3S811 Evaluation Board" ftdi_vid_pid 0x0403 0xbcd9 diff --git a/tcl/interface/ftdi/luminary.cfg b/tcl/interface/ftdi/luminary.cfg index 20b54220e..5e34f8cea 100644 --- a/tcl/interface/ftdi/luminary.cfg +++ b/tcl/interface/ftdi/luminary.cfg @@ -24,7 +24,7 @@ # firmware via the ITM module as well as profile data. # -interface ftdi +adapter driver ftdi ftdi_device_desc "Stellaris Evaluation Board" ftdi_vid_pid 0x0403 0xbcd9 diff --git a/tcl/interface/ftdi/m53evk.cfg b/tcl/interface/ftdi/m53evk.cfg index 2b9727049..6597f2d30 100644 --- a/tcl/interface/ftdi/m53evk.cfg +++ b/tcl/interface/ftdi/m53evk.cfg @@ -4,7 +4,7 @@ # http://www.denx-cs.de/?q=M53EVK # -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/mbftdi.cfg b/tcl/interface/ftdi/mbftdi.cfg index d051cccb0..c0ff86574 100644 --- a/tcl/interface/ftdi/mbftdi.cfg +++ b/tcl/interface/ftdi/mbftdi.cfg @@ -9,7 +9,7 @@ # and http://www.marsohod.org/plata-marsokhod3 for details. # -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/minimodule-swd.cfg b/tcl/interface/ftdi/minimodule-swd.cfg index 5f0b212f5..7ab46503e 100644 --- a/tcl/interface/ftdi/minimodule-swd.cfg +++ b/tcl/interface/ftdi/minimodule-swd.cfg @@ -34,7 +34,7 @@ Supports SWD using the FT2232H or FT4232H minimodule. # CN2-22 - nRESET # -interface ftdi +adapter driver ftdi #Select your module type and channel diff --git a/tcl/interface/ftdi/minimodule.cfg b/tcl/interface/ftdi/minimodule.cfg index 7df096d9c..5dcce1fcf 100644 --- a/tcl/interface/ftdi/minimodule.cfg +++ b/tcl/interface/ftdi/minimodule.cfg @@ -4,7 +4,7 @@ # http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_FT2232H_Mini_Module.pdf # -interface ftdi +adapter driver ftdi ftdi_device_desc "FT2232H MiniModule" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/minispartan6.cfg b/tcl/interface/ftdi/minispartan6.cfg index 8f1601192..92aebbcfd 100644 --- a/tcl/interface/ftdi/minispartan6.cfg +++ b/tcl/interface/ftdi/minispartan6.cfg @@ -1,6 +1,6 @@ # https://www.scarabhardware.com/minispartan6/ # https://github.com/scarabhardware/miniSpartan6-plus/raw/master/miniSpartan6%2B_Rev_B.pdf -interface ftdi +adapter driver ftdi # The miniSpartan6+ sadly doesn't have a custom device description, so we just # have to hope you got it right. #ftdi_device_desc "Dual RS232-HS" diff --git a/tcl/interface/ftdi/neodb.cfg b/tcl/interface/ftdi/neodb.cfg index 6cc8ccf71..1cfb3526c 100644 --- a/tcl/interface/ftdi/neodb.cfg +++ b/tcl/interface/ftdi/neodb.cfg @@ -4,7 +4,7 @@ # http://wiki.openmoko.org/wiki/Debug_Board_v3 # -interface ftdi +adapter driver ftdi ftdi_device_desc "Debug Board for Neo1973" ftdi_vid_pid 0x1457 0x5118 diff --git a/tcl/interface/ftdi/ngxtech.cfg b/tcl/interface/ftdi/ngxtech.cfg index 9eaa3c5bc..3aa79ab31 100644 --- a/tcl/interface/ftdi/ngxtech.cfg +++ b/tcl/interface/ftdi/ngxtech.cfg @@ -10,7 +10,7 @@ echo "interface uses the same layout as configs that were verified. Please repor echo "experience with this file to openocd-devel mailing list, so it could be marked" echo "as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "NGX JTAG" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg b/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg index 5b27d38ba..c8e3befb7 100644 --- a/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg +++ b/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg @@ -4,7 +4,7 @@ # http://www.olimex.com/dev/arm-usb-ocd-h.html # -interface ftdi +adapter driver ftdi ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-OCD-H" ftdi_vid_pid 0x15ba 0x002b diff --git a/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg b/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg index e1aeeeab6..f9126d40d 100644 --- a/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg +++ b/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg @@ -4,7 +4,7 @@ # http://www.olimex.com/dev/arm-usb-ocd.html # -interface ftdi +adapter driver ftdi ftdi_device_desc "Olimex OpenOCD JTAG" ftdi_vid_pid 0x15ba 0x0003 diff --git a/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg b/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg index f77c24b2c..eac25b6da 100644 --- a/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg +++ b/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg @@ -4,7 +4,7 @@ # http://www.olimex.com/dev/arm-usb-tiny-h.html # -interface ftdi +adapter driver ftdi ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H" ftdi_vid_pid 0x15ba 0x002a diff --git a/tcl/interface/ftdi/olimex-jtag-tiny.cfg b/tcl/interface/ftdi/olimex-jtag-tiny.cfg index b3c6a716e..4811f4dda 100644 --- a/tcl/interface/ftdi/olimex-jtag-tiny.cfg +++ b/tcl/interface/ftdi/olimex-jtag-tiny.cfg @@ -4,7 +4,7 @@ # http://www.olimex.com/dev/arm-usb-tiny.html # -interface ftdi +adapter driver ftdi ftdi_device_desc "Olimex OpenOCD JTAG TINY" ftdi_vid_pid 0x15ba 0x0004 diff --git a/tcl/interface/ftdi/oocdlink.cfg b/tcl/interface/ftdi/oocdlink.cfg index fc09a1636..deba4a504 100644 --- a/tcl/interface/ftdi/oocdlink.cfg +++ b/tcl/interface/ftdi/oocdlink.cfg @@ -10,7 +10,7 @@ echo "interface uses the same layout as configs that were verified. Please repor echo "experience with this file to openocd-devel mailing list, so it could be marked" echo "as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "OOCDLink" ftdi_vid_pid 0x0403 0xbaf8 diff --git a/tcl/interface/ftdi/opendous_ftdi.cfg b/tcl/interface/ftdi/opendous_ftdi.cfg index 6a12d7212..50f32fb3a 100644 --- a/tcl/interface/ftdi/opendous_ftdi.cfg +++ b/tcl/interface/ftdi/opendous_ftdi.cfg @@ -7,7 +7,7 @@ # (and it has a different pid number). # -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 ftdi_channel 1 diff --git a/tcl/interface/ftdi/openocd-usb-hs.cfg b/tcl/interface/ftdi/openocd-usb-hs.cfg index 37a717dc5..6f67689f6 100644 --- a/tcl/interface/ftdi/openocd-usb-hs.cfg +++ b/tcl/interface/ftdi/openocd-usb-hs.cfg @@ -4,7 +4,7 @@ # http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14 # -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232-HS" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/openocd-usb.cfg b/tcl/interface/ftdi/openocd-usb.cfg index ff537c7b6..ed80a05d9 100644 --- a/tcl/interface/ftdi/openocd-usb.cfg +++ b/tcl/interface/ftdi/openocd-usb.cfg @@ -4,7 +4,7 @@ # http://www.hs-augsburg.de/~hhoegl/proj/usbjtag/usbjtag.html # -interface ftdi +adapter driver ftdi ftdi_device_desc "Dual RS232" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/openrd.cfg b/tcl/interface/ftdi/openrd.cfg index 9ec5b5f65..535c5e896 100644 --- a/tcl/interface/ftdi/openrd.cfg +++ b/tcl/interface/ftdi/openrd.cfg @@ -4,7 +4,7 @@ # http://www.marvell.com/products/embedded_processors/developer/kirkwood/openrd.jsp # -interface ftdi +adapter driver ftdi ftdi_device_desc "OpenRD JTAGKey FT2232D B" ftdi_vid_pid 0x0403 0x9e90 ftdi_channel 0 diff --git a/tcl/interface/ftdi/pipistrello.cfg b/tcl/interface/ftdi/pipistrello.cfg index 5ee5be5bb..4e392942a 100644 --- a/tcl/interface/ftdi/pipistrello.cfg +++ b/tcl/interface/ftdi/pipistrello.cfg @@ -1,6 +1,6 @@ # http://pipistrello.saanlima.com/ # http://www.saanlima.com/download/pipistrello-v2.0/pipistrello_v2_schematic.pdf -interface ftdi +adapter driver ftdi ftdi_device_desc "Pipistrello LX45" ftdi_vid_pid 0x0403 0x6010 # interface 1 is the uart diff --git a/tcl/interface/ftdi/redbee-econotag.cfg b/tcl/interface/ftdi/redbee-econotag.cfg index 70c30d658..b6f6d23ba 100644 --- a/tcl/interface/ftdi/redbee-econotag.cfg +++ b/tcl/interface/ftdi/redbee-econotag.cfg @@ -13,7 +13,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6010 ftdi_layout_init 0x0c08 0x0c2b diff --git a/tcl/interface/ftdi/redbee-usb.cfg b/tcl/interface/ftdi/redbee-usb.cfg index b79300d53..52ab93e02 100644 --- a/tcl/interface/ftdi/redbee-usb.cfg +++ b/tcl/interface/ftdi/redbee-usb.cfg @@ -13,7 +13,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x6010 ftdi_channel 1 diff --git a/tcl/interface/ftdi/sheevaplug.cfg b/tcl/interface/ftdi/sheevaplug.cfg index 625aad398..d4ec72e66 100644 --- a/tcl/interface/ftdi/sheevaplug.cfg +++ b/tcl/interface/ftdi/sheevaplug.cfg @@ -4,7 +4,7 @@ # http://www.marvell.com/products/embedded_processors/developer/kirkwood/sheevaplug.jsp # -interface ftdi +adapter driver ftdi ftdi_device_desc "SheevaPlug JTAGKey FT2232D B" ftdi_vid_pid 0x9e88 0x9e8f ftdi_channel 0 diff --git a/tcl/interface/ftdi/signalyzer-lite.cfg b/tcl/interface/ftdi/signalyzer-lite.cfg index 4988a3bfd..477842005 100644 --- a/tcl/interface/ftdi/signalyzer-lite.cfg +++ b/tcl/interface/ftdi/signalyzer-lite.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "Signalyzer LITE" ftdi_vid_pid 0x0403 0xbca1 diff --git a/tcl/interface/ftdi/signalyzer.cfg b/tcl/interface/ftdi/signalyzer.cfg index e2629beec..243929835 100644 --- a/tcl/interface/ftdi/signalyzer.cfg +++ b/tcl/interface/ftdi/signalyzer.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on code in ft223 echo "Please report your experience with this file to openocd-devel mailing list," echo "so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "Signalyzer" ftdi_vid_pid 0x0403 0xbca0 diff --git a/tcl/interface/ftdi/stm32-stick.cfg b/tcl/interface/ftdi/stm32-stick.cfg index 2aff1fe8f..7ae02bd80 100644 --- a/tcl/interface/ftdi/stm32-stick.cfg +++ b/tcl/interface/ftdi/stm32-stick.cfg @@ -4,7 +4,7 @@ # http://www.hitex.com/index.php?id=340 # -interface ftdi +adapter driver ftdi ftdi_device_desc "STM32-PerformanceStick" ftdi_vid_pid 0x0640 0x002d diff --git a/tcl/interface/ftdi/ti-icdi.cfg b/tcl/interface/ftdi/ti-icdi.cfg index 6af809cd9..55085eaee 100644 --- a/tcl/interface/ftdi/ti-icdi.cfg +++ b/tcl/interface/ftdi/ti-icdi.cfg @@ -6,7 +6,7 @@ # support) but the USB IDs are different. # -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0451 0xc32a ftdi_layout_init 0x00a8 0x00eb diff --git a/tcl/interface/ftdi/tumpa-lite.cfg b/tcl/interface/ftdi/tumpa-lite.cfg index 657515a91..7f576e91d 100644 --- a/tcl/interface/ftdi/tumpa-lite.cfg +++ b/tcl/interface/ftdi/tumpa-lite.cfg @@ -4,7 +4,7 @@ # http://www.diygadget.com/tiao-usb-multi-protocol-adapter-lite-jtag-spi-i2c-serial.html # -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x8a99 ftdi_layout_init 0x0038 0x087b diff --git a/tcl/interface/ftdi/tumpa.cfg b/tcl/interface/ftdi/tumpa.cfg index e4b59b118..1a4e3cdfa 100644 --- a/tcl/interface/ftdi/tumpa.cfg +++ b/tcl/interface/ftdi/tumpa.cfg @@ -4,7 +4,7 @@ # http://www.diygadget.com/tiao-usb-multi-protocol-adapter-jtag-spi-i2c-serial.html # -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0x8a98 0x0403 0x6010 ftdi_layout_init 0x0038 0x087b diff --git a/tcl/interface/ftdi/turtelizer2-revB.cfg b/tcl/interface/ftdi/turtelizer2-revB.cfg index 45840402a..34ae86129 100644 --- a/tcl/interface/ftdi/turtelizer2-revB.cfg +++ b/tcl/interface/ftdi/turtelizer2-revB.cfg @@ -9,7 +9,7 @@ echo "This file was not tested with real interface, it is based on schematics an echo "in ft2232.c. Please report your experience with this file to openocd-devel" echo "mailing list, so it could be marked as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "Turtelizer JTAG/RS232 Adapter" ftdi_vid_pid 0x0403 0xbdc8 diff --git a/tcl/interface/ftdi/turtelizer2-revC.cfg b/tcl/interface/ftdi/turtelizer2-revC.cfg index 918ac497b..f5192fb31 100644 --- a/tcl/interface/ftdi/turtelizer2-revC.cfg +++ b/tcl/interface/ftdi/turtelizer2-revC.cfg @@ -4,7 +4,7 @@ # http://www.ethernut.de/en/hardware/turtelizer/index.html # -interface ftdi +adapter driver ftdi ftdi_device_desc "Turtelizer JTAG/RS232 Adapter" ftdi_vid_pid 0x0403 0xbdc8 diff --git a/tcl/interface/ftdi/um232h.cfg b/tcl/interface/ftdi/um232h.cfg index 6ba6f43b2..2dabbec4a 100644 --- a/tcl/interface/ftdi/um232h.cfg +++ b/tcl/interface/ftdi/um232h.cfg @@ -7,7 +7,7 @@ # Note that UM232H and UM232H-B are 3.3V only. # -interface ftdi +adapter driver ftdi #ftdi_device_desc "UM232H" ftdi_vid_pid 0x0403 0x6014 diff --git a/tcl/interface/ftdi/vpaclink.cfg b/tcl/interface/ftdi/vpaclink.cfg index 205761964..ed4895a6b 100644 --- a/tcl/interface/ftdi/vpaclink.cfg +++ b/tcl/interface/ftdi/vpaclink.cfg @@ -10,7 +10,7 @@ echo "interface uses the same layout as configs that were verified. Please repor echo "experience with this file to openocd-devel mailing list, so it could be marked" echo "as working or fixed." -interface ftdi +adapter driver ftdi ftdi_device_desc "VPACLink" ftdi_vid_pid 0x0403 0x6010 diff --git a/tcl/interface/ftdi/xds100v2.cfg b/tcl/interface/ftdi/xds100v2.cfg index 2628aa086..860a7585d 100644 --- a/tcl/interface/ftdi/xds100v2.cfg +++ b/tcl/interface/ftdi/xds100v2.cfg @@ -7,7 +7,7 @@ # to the registered TI users. # -interface ftdi +adapter driver ftdi ftdi_vid_pid 0x0403 0xa6d0 0x0403 0x6010 ftdi_layout_init 0x0038 0x597b diff --git a/tcl/interface/imx-native.cfg b/tcl/interface/imx-native.cfg index c2f80eb59..d9bc7eb04 100644 --- a/tcl/interface/imx-native.cfg +++ b/tcl/interface/imx-native.cfg @@ -7,7 +7,7 @@ # # -interface imx_gpio +adapter driver imx_gpio # For most IMX processors 0x0209c000 imx_gpio_peripheral_base 0x0209c000 diff --git a/tcl/interface/jlink.cfg b/tcl/interface/jlink.cfg index a4f9dddd7..51f420b7f 100644 --- a/tcl/interface/jlink.cfg +++ b/tcl/interface/jlink.cfg @@ -4,7 +4,7 @@ # http://www.segger.com/jlink.html # -interface jlink +adapter driver jlink # The serial number can be used to select a specific device in case more than # one is connected to the host. diff --git a/tcl/interface/jtag_vpi.cfg b/tcl/interface/jtag_vpi.cfg index a37a11ed0..e665a6331 100644 --- a/tcl/interface/jtag_vpi.cfg +++ b/tcl/interface/jtag_vpi.cfg @@ -1,4 +1,4 @@ -interface jtag_vpi +adapter driver jtag_vpi # Set the VPI JTAG server port if { [info exists VPI_PORT] } { diff --git a/tcl/interface/kitprog.cfg b/tcl/interface/kitprog.cfg index 94497147f..29fce489b 100644 --- a/tcl/interface/kitprog.cfg +++ b/tcl/interface/kitprog.cfg @@ -6,7 +6,7 @@ # interface driver or switch the KitProg to KitProg mode. # -interface kitprog +adapter driver kitprog # Optionally specify the serial number of the KitProg you want to use. #kitprog_serial 1926402735485200 diff --git a/tcl/interface/nds32-aice.cfg b/tcl/interface/nds32-aice.cfg index 5363b4c1d..8f32c899c 100644 --- a/tcl/interface/nds32-aice.cfg +++ b/tcl/interface/nds32-aice.cfg @@ -4,7 +4,7 @@ # http://www.andestech.com # -interface aice +adapter driver aice aice desc "Andes AICE adapter" aice serial "C001-42163" aice vid_pid 0x1CFC 0x0000 diff --git a/tcl/interface/opendous.cfg b/tcl/interface/opendous.cfg index 21ced6fbe..23fddc69c 100644 --- a/tcl/interface/opendous.cfg +++ b/tcl/interface/opendous.cfg @@ -4,4 +4,4 @@ # http://code.google.com/p/opendous-jtag/ # -interface opendous +adapter driver opendous diff --git a/tcl/interface/openjtag.cfg b/tcl/interface/openjtag.cfg index b20c22b6c..7bd532545 100644 --- a/tcl/interface/openjtag.cfg +++ b/tcl/interface/openjtag.cfg @@ -4,5 +4,5 @@ # www.openjtag.org # -interface openjtag +adapter driver openjtag openjtag_device_desc "Open JTAG Project" \ No newline at end of file diff --git a/tcl/interface/osbdm.cfg b/tcl/interface/osbdm.cfg index e88ce50b5..6e88c0736 100644 --- a/tcl/interface/osbdm.cfg +++ b/tcl/interface/osbdm.cfg @@ -3,5 +3,5 @@ # # http://pemicro.com/osbdm/ # -interface osbdm +adapter driver osbdm reset_config srst_only diff --git a/tcl/interface/parport.cfg b/tcl/interface/parport.cfg index ae3f8f158..4c0b260b9 100644 --- a/tcl/interface/parport.cfg +++ b/tcl/interface/parport.cfg @@ -14,6 +14,6 @@ if { [info exists PARPORTADDR] } { } } -interface parport +adapter driver parport parport_port $_PARPORTADDR parport_cable wiggler diff --git a/tcl/interface/parport_dlc5.cfg b/tcl/interface/parport_dlc5.cfg index 98345808e..b1aa0a9a7 100644 --- a/tcl/interface/parport_dlc5.cfg +++ b/tcl/interface/parport_dlc5.cfg @@ -10,7 +10,7 @@ if { [info exists PARPORTADDR] } { set _PARPORTADDR 0 } -interface parport +adapter driver parport parport_port $_PARPORTADDR parport_cable dlc5 diff --git a/tcl/interface/raspberrypi-native.cfg b/tcl/interface/raspberrypi-native.cfg index c63dfdbc7..2d0547f31 100644 --- a/tcl/interface/raspberrypi-native.cfg +++ b/tcl/interface/raspberrypi-native.cfg @@ -8,7 +8,7 @@ # Do not forget the GND connection, pin 6 of the expansion header. # -interface bcm2835gpio +adapter driver bcm2835gpio bcm2835gpio_peripheral_base 0x20000000 diff --git a/tcl/interface/raspberrypi2-native.cfg b/tcl/interface/raspberrypi2-native.cfg index 26a31c55e..e53b0f3b0 100644 --- a/tcl/interface/raspberrypi2-native.cfg +++ b/tcl/interface/raspberrypi2-native.cfg @@ -8,7 +8,7 @@ # Do not forget the GND connection, pin 6 of the expansion header. # -interface bcm2835gpio +adapter driver bcm2835gpio bcm2835gpio_peripheral_base 0x3F000000 diff --git a/tcl/interface/rlink.cfg b/tcl/interface/rlink.cfg index 2f13cc489..3fe90ab42 100644 --- a/tcl/interface/rlink.cfg +++ b/tcl/interface/rlink.cfg @@ -4,5 +4,5 @@ # http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html # -interface rlink +adapter driver rlink diff --git a/tcl/interface/stlink.cfg b/tcl/interface/stlink.cfg index 735ad5a4e..e9a7b17b1 100644 --- a/tcl/interface/stlink.cfg +++ b/tcl/interface/stlink.cfg @@ -3,7 +3,7 @@ # debugger/programmer # -interface hla +adapter driver hla hla_layout stlink hla_device_desc "ST-LINK" hla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 diff --git a/tcl/interface/sysfsgpio-raspberrypi.cfg b/tcl/interface/sysfsgpio-raspberrypi.cfg index 9f5b87c38..ebb150219 100644 --- a/tcl/interface/sysfsgpio-raspberrypi.cfg +++ b/tcl/interface/sysfsgpio-raspberrypi.cfg @@ -8,7 +8,7 @@ # Do not forget the GND connection, pin 6 of the expansion header. # -interface sysfsgpio +adapter driver sysfsgpio # Each of the JTAG lines need a gpio number set: tck tms tdi tdo # Header pin numbers: 23 22 19 21 diff --git a/tcl/interface/ti-icdi.cfg b/tcl/interface/ti-icdi.cfg index 0fc3a9b67..9b46b437c 100644 --- a/tcl/interface/ti-icdi.cfg +++ b/tcl/interface/ti-icdi.cfg @@ -7,7 +7,7 @@ # http://www.ti.com/tool/ek-lm4f232 # -interface hla +adapter driver hla hla_layout ti-icdi hla_vid_pid 0x1cbe 0x00fd diff --git a/tcl/interface/ulink.cfg b/tcl/interface/ulink.cfg index 3b1fad071..164b990a1 100644 --- a/tcl/interface/ulink.cfg +++ b/tcl/interface/ulink.cfg @@ -5,4 +5,4 @@ # http://article.gmane.org/gmane.comp.debugging.openocd.devel/17362 # -interface ulink +adapter driver ulink diff --git a/tcl/interface/usb-jtag.cfg b/tcl/interface/usb-jtag.cfg index cb4d29bbc..8617c78c3 100644 --- a/tcl/interface/usb-jtag.cfg +++ b/tcl/interface/usb-jtag.cfg @@ -29,7 +29,7 @@ # level driver. Loading firmware is currently only supported on the ublast2 # driver but ixo-usb-jtag requires the ftdi driver. -interface usb_blaster +adapter driver usb_blaster usb_blaster_vid_pid 0x16C0 0x06AD usb_blaster_device_desc "Van Ooijen Technische Informatica" # ixo-usb-jtag is only compatible with the ublast1 protocol implemented via the diff --git a/tcl/interface/usbprog.cfg b/tcl/interface/usbprog.cfg index b4f0da328..f65c1d473 100644 --- a/tcl/interface/usbprog.cfg +++ b/tcl/interface/usbprog.cfg @@ -4,7 +4,7 @@ # http://embedded-projects.net/index.php?page_id=135 # -interface usbprog +adapter driver usbprog # USBprog is broken w/short TMS sequences, this is a workaround # until the C code can be fixed. tms_sequence long diff --git a/tcl/interface/vsllink.cfg b/tcl/interface/vsllink.cfg index fad793490..a587176ae 100644 --- a/tcl/interface/vsllink.cfg +++ b/tcl/interface/vsllink.cfg @@ -4,5 +4,5 @@ # http://www.versaloon.com/ # -interface vsllink +adapter driver vsllink diff --git a/tcl/interface/xds110.cfg b/tcl/interface/xds110.cfg index 495e20258..edc438d3b 100644 --- a/tcl/interface/xds110.cfg +++ b/tcl/interface/xds110.cfg @@ -5,7 +5,7 @@ # http://processors.wiki.ti.com/index.php/Emulation_Software_Package#XDS110_Support_Utilities # -interface xds110 +adapter driver xds110 # Use serial number option to use a specific XDS110 # when more than one are connected to the host. From 0d598535a30ea553f5a5d4a0047010807fcc5996 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 23 Aug 2019 16:07:12 +0200 Subject: [PATCH 110/354] doc: replace example command "interface" with "adapter driver" Keep documentation consisted after commands renaming. Change-Id: I97b43887cae9d7c224b07e4ba0b7d04915a19fc4 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5285 Tested-by: jenkins Reviewed-by: Marc Schink Reviewed-by: Oleksij Rempel --- doc/openocd.texi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index b203656fc..1c89d8c0b 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -2338,7 +2338,7 @@ A few cases are so simple that you only need to say what driver to use: @example # jlink interface -interface jlink +adapter driver jlink @end example Most adapters need a bit more configuration than that. @@ -2719,7 +2719,7 @@ For example, to connect remotely via TCP to the host foobar you might have something like: @example -interface remote_bitbang +adapter driver remote_bitbang remote_bitbang_port 3335 remote_bitbang_host foobar @end example @@ -2728,7 +2728,7 @@ To connect to another process running locally via UNIX sockets with socket named mysocket: @example -interface remote_bitbang +adapter driver remote_bitbang remote_bitbang_port 0 remote_bitbang_host mysocket @end example @@ -3036,7 +3036,7 @@ For example, the interface configuration file for a classic ``Wiggler'' cable on LPT2 might look something like this: @example -interface parport +adapter driver parport parport_port 0x278 parport_cable wiggler @end example From 38ac08c1c25adf42cf20e48e10e6ddeab6a12d71 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 23 Aug 2019 15:51:00 +0200 Subject: [PATCH 111/354] tcl: replace the deprecated commands with "adapter ..." Avoid annoying "deprecated" messages while running the scripts distributed with OpenOCD code. Change automatically created with commands sed -i 's/adapter_khz/adapter speed/g' $(find tcl/ -type f) sed -i 's/adapter_nsrst_delay/adapter srst delay/g' $(find tcl/ -type f) sed -i 's/adapter_nsrst_assert_width/adapter srst pulse_width/g' $(find tcl/ -type f) Minor indentation issue fixed manually in tcl/board/at91sam9g20-ek.cfg tcl/target/at91sam9260_ext_RAM_ext_flash.cfg Change-Id: I425fd56c0c88cd6b06124621306eeb89166dfe71 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5284 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/board/actux3.cfg | 2 +- tcl/board/adsp-sc584-ezbrd.cfg | 2 +- tcl/board/altera_sockit.cfg | 2 +- tcl/board/arm_musca_a.cfg | 2 +- tcl/board/arty_s7.cfg | 2 +- tcl/board/at91cap7a-stk-sdram.cfg | 4 ++-- tcl/board/at91eb40a.cfg | 2 +- tcl/board/at91rm9200-dk.cfg | 4 ++-- tcl/board/at91rm9200-ek.cfg | 6 +++--- tcl/board/at91sam9g20-ek.cfg | 6 +++--- tcl/board/atmel_sam3n_ek.cfg | 2 +- tcl/board/avnet_ultrazed-eg.cfg | 2 +- tcl/board/bcm28155_ap.cfg | 2 +- tcl/board/colibri.cfg | 2 +- tcl/board/crossbow_tech_imote2.cfg | 2 +- tcl/board/csb337.cfg | 4 ++-- tcl/board/csb732.cfg | 2 +- tcl/board/digi_connectcore_wi-9c.cfg | 2 +- tcl/board/digilent_analog_discovery.cfg | 2 +- tcl/board/dm365evm.cfg | 2 +- tcl/board/dp_busblaster_v3.cfg | 2 +- tcl/board/efm32.cfg | 2 +- tcl/board/ek-lm3s1968.cfg | 2 +- tcl/board/embedded-artists_lpc2478-32.cfg | 2 +- tcl/board/emcraft_imx8m-som-bsb.cfg | 4 ++-- tcl/board/ethernut3.cfg | 4 ++-- tcl/board/fsl_imx6q_sabresd.cfg | 4 ++-- tcl/board/glyn_tonga2.cfg | 6 +++--- tcl/board/hilscher_nxdb500sys.cfg | 2 +- tcl/board/hilscher_nxeb500hmi.cfg | 2 +- tcl/board/hilscher_nxhx10.cfg | 2 +- tcl/board/hilscher_nxhx50.cfg | 2 +- tcl/board/hilscher_nxhx500.cfg | 2 +- tcl/board/hilscher_nxsb100.cfg | 2 +- tcl/board/hitex_lpc1768stick.cfg | 2 +- tcl/board/hitex_lpc2929.cfg | 8 ++++---- tcl/board/hitex_stm32-performancestick.cfg | 2 +- tcl/board/hitex_str9-comstick.cfg | 4 ++-- tcl/board/icnova_imx53_sodimm.cfg | 4 ++-- tcl/board/icnova_sam9g45_sodimm.cfg | 6 +++--- tcl/board/imx27lnst.cfg | 2 +- tcl/board/imx53-m53evk.cfg | 2 +- tcl/board/imx53loco.cfg | 4 ++-- tcl/board/insignal_arndale.cfg | 2 +- tcl/board/kasli.cfg | 2 +- tcl/board/kc705.cfg | 2 +- tcl/board/kcu105.cfg | 2 +- tcl/board/kindle2.cfg | 4 ++-- tcl/board/lubbock.cfg | 2 +- tcl/board/marsohod.cfg | 2 +- tcl/board/marsohod2.cfg | 2 +- tcl/board/marsohod3.cfg | 2 +- tcl/board/mcb1700.cfg | 4 ++-- tcl/board/microchip_saml11_xplained_pro.cfg | 2 +- tcl/board/mini2440.cfg | 6 +++--- tcl/board/mini6410.cfg | 4 ++-- tcl/board/numato_mimas_a7.cfg | 2 +- tcl/board/nxp_imx7sabre.cfg | 4 ++-- tcl/board/nxp_mcimx8m-evk.cfg | 4 ++-- tcl/board/olimex_sam7_la2.cfg | 8 ++++---- tcl/board/openrd.cfg | 2 +- tcl/board/or1k_generic.cfg | 2 +- tcl/board/phytec_lpc3250.cfg | 8 ++++---- tcl/board/pxa255_sst.cfg | 2 +- tcl/board/quark_d2000_refboard.cfg | 2 +- tcl/board/quark_x10xx_board.cfg | 2 +- tcl/board/rsc-w910.cfg | 8 ++++---- tcl/board/sayma_amc.cfg | 2 +- tcl/board/sheevaplug.cfg | 2 +- tcl/board/sifive-e31arty.cfg | 2 +- tcl/board/sifive-e51arty.cfg | 2 +- tcl/board/sifive-hifive1.cfg | 4 ++-- tcl/board/telo.cfg | 8 ++++---- tcl/board/ti_am437x_idk.cfg | 2 +- tcl/board/ti_am43xx_evm.cfg | 2 +- tcl/board/ti_beaglebone.cfg | 2 +- tcl/board/ti_beaglebone_black.cfg | 2 +- tcl/board/ti_cc13x0_launchpad.cfg | 2 +- tcl/board/ti_cc13x2_launchpad.cfg | 2 +- tcl/board/ti_cc26x0_launchpad.cfg | 2 +- tcl/board/ti_cc26x2_launchpad.cfg | 2 +- tcl/board/ti_cc3200_launchxl.cfg | 2 +- tcl/board/ti_cc3220sf_launchpad.cfg | 2 +- tcl/board/ti_cc32xx_launchpad.cfg | 2 +- tcl/board/ti_msp432_launchpad.cfg | 2 +- tcl/board/ti_tmdx570ls31usb.cfg | 2 +- tcl/board/tocoding_poplar.cfg | 2 +- tcl/board/topas910.cfg | 2 +- tcl/board/topasa900.cfg | 2 +- tcl/board/twr-vf65gs10.cfg | 2 +- tcl/board/verdex.cfg | 2 +- tcl/board/voltcraft_dso-3062c.cfg | 2 +- tcl/board/zy1000.cfg | 2 +- tcl/interface/calao-usb-a9260.cfg | 2 +- tcl/interface/ft232r.cfg | 2 +- tcl/interface/ftdi/minispartan6.cfg | 2 +- tcl/interface/ftdi/pipistrello.cfg | 2 +- tcl/interface/nds32-aice.cfg | 2 +- tcl/target/1986ве1т.cfg | 4 ++-- tcl/target/aduc702x.cfg | 2 +- tcl/target/aducm360.cfg | 4 ++-- tcl/target/allwinner_v3s.cfg | 2 +- tcl/target/altera_fpgasoc.cfg | 6 +++--- tcl/target/amdm37x.cfg | 6 +++--- tcl/target/ar71xx.cfg | 2 +- tcl/target/at91sam3XXX.cfg | 4 ++-- tcl/target/at91sam4XXX.cfg | 4 ++-- tcl/target/at91sam4lXX.cfg | 4 ++-- tcl/target/at91sam9.cfg | 4 ++-- tcl/target/at91sam9260_ext_RAM_ext_flash.cfg | 8 ++++---- tcl/target/at91sam9g20.cfg | 2 +- tcl/target/at91samdXX.cfg | 4 ++-- tcl/target/atheros_ar9331.cfg | 4 ++-- tcl/target/atmega128.cfg | 6 +++--- tcl/target/atmega128rfa1.cfg | 2 +- tcl/target/atsame5x.cfg | 2 +- tcl/target/atsamv.cfg | 2 +- tcl/target/avr32.cfg | 2 +- tcl/target/bcm6348.cfg | 2 +- tcl/target/bluenrg-x.cfg | 2 +- tcl/target/c100.cfg | 2 +- tcl/target/c100helper.tcl | 2 +- tcl/target/cc2538.cfg | 2 +- tcl/target/dragonite.cfg | 2 +- tcl/target/dsp56321.cfg | 2 +- tcl/target/dsp568013.cfg | 2 +- tcl/target/dsp568037.cfg | 2 +- tcl/target/efm32.cfg | 2 +- tcl/target/epc9301.cfg | 2 +- tcl/target/esi32xx.cfg | 2 +- tcl/target/feroceon.cfg | 2 +- tcl/target/fm3.cfg | 4 ++-- tcl/target/fm4.cfg | 2 +- tcl/target/gp326xxxa.cfg | 8 ++++---- tcl/target/imx28.cfg | 2 +- tcl/target/imx31.cfg | 2 +- tcl/target/imx6.cfg | 4 ++-- tcl/target/is5114.cfg | 6 +++--- tcl/target/k1921vk01t.cfg | 4 ++-- tcl/target/ke0x.cfg | 2 +- tcl/target/klx.cfg | 2 +- tcl/target/ks869x.cfg | 2 +- tcl/target/kx.cfg | 2 +- tcl/target/lpc1850.cfg | 2 +- tcl/target/lpc1xxx.cfg | 4 ++-- tcl/target/lpc2xxx.cfg | 4 ++-- tcl/target/lpc3131.cfg | 2 +- tcl/target/lpc4350.cfg | 2 +- tcl/target/lpc4370.cfg | 2 +- tcl/target/lpc8nxx.cfg | 2 +- tcl/target/ls1012a.cfg | 2 +- tcl/target/max32620.cfg | 2 +- tcl/target/max32625.cfg | 2 +- tcl/target/max3263x.cfg | 2 +- tcl/target/mc13224v.cfg | 4 ++-- tcl/target/mdr32f9q2i.cfg | 4 ++-- tcl/target/nrf51.cfg | 2 +- tcl/target/nrf52.cfg | 2 +- tcl/target/numicro.cfg | 2 +- tcl/target/omap3530.cfg | 4 ++-- tcl/target/omap5912.cfg | 2 +- tcl/target/omapl138.cfg | 4 ++-- tcl/target/pic32mx.cfg | 2 +- tcl/target/psoc4.cfg | 6 +++--- tcl/target/psoc6.cfg | 2 +- tcl/target/pxa255.cfg | 4 ++-- tcl/target/pxa270.cfg | 4 ++-- tcl/target/pxa3xx.cfg | 4 ++-- tcl/target/qualcomm_qca4531.cfg | 4 ++-- tcl/target/readme.txt | 6 +++--- tcl/target/renesas_s7g2.cfg | 2 +- tcl/target/samsung_s3c2450.cfg | 4 ++-- tcl/target/samsung_s3c6410.cfg | 2 +- tcl/target/sim3x.cfg | 4 ++-- tcl/target/smp8634.cfg | 2 +- tcl/target/stellaris.cfg | 4 ++-- tcl/target/stm32f0x.cfg | 8 ++++---- tcl/target/stm32f1x.cfg | 4 ++-- tcl/target/stm32f2x.cfg | 4 ++-- tcl/target/stm32f3x.cfg | 8 ++++---- tcl/target/stm32f4x.cfg | 8 ++++---- tcl/target/stm32f7x.cfg | 8 ++++---- tcl/target/stm32h7x.cfg | 6 +++--- tcl/target/stm32l0.cfg | 8 ++++---- tcl/target/stm32l1.cfg | 8 ++++---- tcl/target/stm32l4x.cfg | 8 ++++---- tcl/target/stm8l.cfg | 2 +- tcl/target/stm8s.cfg | 2 +- tcl/target/str710.cfg | 6 +++--- tcl/target/str730.cfg | 8 ++++---- tcl/target/str750.cfg | 8 ++++---- tcl/target/str912.cfg | 8 ++++---- tcl/target/ti_calypso.cfg | 2 +- tcl/target/ti_cc26x0.cfg | 2 +- tcl/target/ti_cc32xx.cfg | 2 +- tcl/target/ti_dm355.cfg | 4 ++-- tcl/target/ti_dm365.cfg | 4 ++-- tcl/target/ti_dm6446.cfg | 4 ++-- tcl/target/ti_msp432.cfg | 2 +- tcl/target/ti_tms570.cfg | 2 +- tcl/target/tmpa900.cfg | 2 +- tcl/target/tmpa910.cfg | 2 +- tcl/target/u8500.cfg | 2 +- tcl/target/vybrid_vf6xx.cfg | 2 +- tcl/target/xmc1xxx.cfg | 2 +- tcl/target/xmc4xxx.cfg | 2 +- tcl/target/zynq_7000.cfg | 2 +- tcl/target/к1879xб1я.cfg | 2 +- tcl/test/syntax1.cfg | 2 +- tcl/tools/firmware-recovery.tcl | 4 ++-- 210 files changed, 332 insertions(+), 332 deletions(-) diff --git a/tcl/board/actux3.cfg b/tcl/board/actux3.cfg index 5435ff885..0de4cb4ca 100644 --- a/tcl/board/actux3.cfg +++ b/tcl/board/actux3.cfg @@ -4,7 +4,7 @@ reset_config trst_and_srst separate -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 source [find target/ixp42x.cfg] diff --git a/tcl/board/adsp-sc584-ezbrd.cfg b/tcl/board/adsp-sc584-ezbrd.cfg index 1054a941f..439fe9268 100644 --- a/tcl/board/adsp-sc584-ezbrd.cfg +++ b/tcl/board/adsp-sc584-ezbrd.cfg @@ -25,7 +25,7 @@ source [find interface/jlink.cfg] transport select swd # chosen speed is 'safe' choice, but your adapter may be capable of more -adapter_khz 400 +adapter speed 400 source [find target/adsp-sc58x.cfg] diff --git a/tcl/board/altera_sockit.cfg b/tcl/board/altera_sockit.cfg index 1466bd46b..3fd01be33 100644 --- a/tcl/board/altera_sockit.cfg +++ b/tcl/board/altera_sockit.cfg @@ -15,5 +15,5 @@ source [find target/altera_fpgasoc.cfg] #usb_blaster_vid_pid 0x6810 0x09fb #usb_blaster_device_desc "USB-Blaster II" -adapter_khz 100 +adapter speed 100 diff --git a/tcl/board/arm_musca_a.cfg b/tcl/board/arm_musca_a.cfg index fa7cf5eef..25f8ce61a 100644 --- a/tcl/board/arm_musca_a.cfg +++ b/tcl/board/arm_musca_a.cfg @@ -15,7 +15,7 @@ source [find target/swj-dp.tcl] # set a safe JTAG clock speed, can be overridden -adapter_khz 1000 +adapter speed 1000 global _CHIPNAME if { [info exists CHIPNAME] } { diff --git a/tcl/board/arty_s7.cfg b/tcl/board/arty_s7.cfg index ca7d3f1c4..5ab408391 100644 --- a/tcl/board/arty_s7.cfg +++ b/tcl/board/arty_s7.cfg @@ -10,7 +10,7 @@ source [find interface/ftdi/digilent-hs1.cfg] source [find cpld/xilinx-xc7.cfg] source [find cpld/jtagspi.cfg] -adapter_khz 25000 +adapter speed 25000 # Usage: # diff --git a/tcl/board/at91cap7a-stk-sdram.cfg b/tcl/board/at91cap7a-stk-sdram.cfg index 9bc02e8c0..a0e393f2c 100644 --- a/tcl/board/at91cap7a-stk-sdram.cfg +++ b/tcl/board/at91cap7a-stk-sdram.cfg @@ -28,7 +28,7 @@ target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAM $_TARGETNAME configure -event reset-start { # start off real slow when we're running off internal RC oscillator - adapter_khz 32 + adapter speed 32 } proc peek32 {address} { @@ -78,7 +78,7 @@ $_TARGETNAME configure -event reset-init { echo "Master clock ok." # Now that we're up and running, crank up speed! - global post_reset_khz ; adapter_khz $post_reset_khz + global post_reset_khz ; adapter speed $post_reset_khz echo "Configuring the SDRAM controller..." diff --git a/tcl/board/at91eb40a.cfg b/tcl/board/at91eb40a.cfg index d8a82a59d..d314e181d 100644 --- a/tcl/board/at91eb40a.cfg +++ b/tcl/board/at91eb40a.cfg @@ -64,4 +64,4 @@ $_TARGETNAME configure -event reset-init { } # This target is pretty snappy... -adapter_khz 16000 +adapter speed 16000 diff --git a/tcl/board/at91rm9200-dk.cfg b/tcl/board/at91rm9200-dk.cfg index f484fded1..b8ec00eab 100644 --- a/tcl/board/at91rm9200-dk.cfg +++ b/tcl/board/at91rm9200-dk.cfg @@ -19,7 +19,7 @@ flash bank $_FLASHNAME cfi 0x10000000 0x00200000 2 2 $_TARGETNAME proc at91rm9200_dk_init { } { # Try to run at 1khz... Yea, that slow! # Chip is really running @ 32khz - adapter_khz 8 + adapter speed 8 mww 0xfffffc64 0xffffffff ## disable all clocks but system clock @@ -45,7 +45,7 @@ proc at91rm9200_dk_init { } { #======================================== # CPU now runs at 180mhz # SYS runs at 60mhz. - adapter_khz 40000 + adapter speed 40000 #======================================== diff --git a/tcl/board/at91rm9200-ek.cfg b/tcl/board/at91rm9200-ek.cfg index a3f253a26..958bc9d51 100644 --- a/tcl/board/at91rm9200-ek.cfg +++ b/tcl/board/at91rm9200-ek.cfg @@ -19,12 +19,12 @@ set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME # The chip may run @ 32khz, so set a really low JTAG speed -adapter_khz 8 +adapter speed 8 proc at91rm9200_ek_init { } { # Try to run at 1khz... Yea, that slow! # Chip is really running @ 32khz - adapter_khz 8 + adapter speed 8 mww 0xfffffc64 0xffffffff ## disable all clocks but system clock @@ -61,7 +61,7 @@ proc at91rm9200_ek_init { } { #======================================== # CPU now runs at 180mhz # SYS runs at 60mhz. - adapter_khz 40000 + adapter speed 40000 #======================================== ## Init SDRAM diff --git a/tcl/board/at91sam9g20-ek.cfg b/tcl/board/at91sam9g20-ek.cfg index 741d6018d..773c8899a 100644 --- a/tcl/board/at91sam9g20-ek.cfg +++ b/tcl/board/at91sam9g20-ek.cfg @@ -19,7 +19,7 @@ set _FLASHTYPE nandflash_cs3 reset_config srst_only -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 200 # If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the @@ -54,7 +54,7 @@ proc at91sam9g20_reset_start { } { # jtag speed without causing GDB keep alive problem. arm7_9 fast_memory_access disable - adapter_khz 2 ;# Slow-speed oscillator enabled at reset, so run jtag speed slow. + adapter speed 2 ;# Slow-speed oscillator enabled at reset, so run jtag speed slow. halt ;# Make sure processor is halted, or error will result in following steps. wait_halt 10000 mww 0xfffffd08 0xa5000501 ;# RSTC_MR : enable user reset. @@ -103,7 +103,7 @@ proc at91sam9g20_reset_init { } { # Switch over to adaptive clocking. - adapter_khz 0 + adapter speed 0 # Enable faster DCC downloads and memory accesses. diff --git a/tcl/board/atmel_sam3n_ek.cfg b/tcl/board/atmel_sam3n_ek.cfg index 2ae73ebfa..e43008f10 100644 --- a/tcl/board/atmel_sam3n_ek.cfg +++ b/tcl/board/atmel_sam3n_ek.cfg @@ -7,6 +7,6 @@ reset_config srst_only set CHIPNAME at91sam3n4c -adapter_khz 32 +adapter speed 32 source [find target/at91sam3nXX.cfg] diff --git a/tcl/board/avnet_ultrazed-eg.cfg b/tcl/board/avnet_ultrazed-eg.cfg index 9879bfcb1..3e4a11a3e 100644 --- a/tcl/board/avnet_ultrazed-eg.cfg +++ b/tcl/board/avnet_ultrazed-eg.cfg @@ -9,7 +9,7 @@ transport select jtag reset_config none # slow default clock -adapter_khz 1000 +adapter speed 1000 set CHIPNAME uscale diff --git a/tcl/board/bcm28155_ap.cfg b/tcl/board/bcm28155_ap.cfg index fb729e191..770ff9cd5 100644 --- a/tcl/board/bcm28155_ap.cfg +++ b/tcl/board/bcm28155_ap.cfg @@ -1,6 +1,6 @@ # BCM28155_AP -adapter_khz 20000 +adapter speed 20000 set CHIPNAME bcm28155 source [find target/bcm281xx.cfg] diff --git a/tcl/board/colibri.cfg b/tcl/board/colibri.cfg index 7c1f1cb51..fe9a3d50e 100644 --- a/tcl/board/colibri.cfg +++ b/tcl/board/colibri.cfg @@ -1,7 +1,7 @@ # Toradex Colibri PXA270 source [find target/pxa270.cfg] reset_config trst_and_srst srst_push_pull -adapter_nsrst_assert_width 40 +adapter srst pulse_width 40 # CS0 -- one bank of CFI flash, 32 MBytes # the bank is 32-bits wide, two 16-bit chips in parallel diff --git a/tcl/board/crossbow_tech_imote2.cfg b/tcl/board/crossbow_tech_imote2.cfg index 002b5372f..277c353a1 100644 --- a/tcl/board/crossbow_tech_imote2.cfg +++ b/tcl/board/crossbow_tech_imote2.cfg @@ -4,7 +4,7 @@ set CHIPNAME imote2 source [find target/pxa270.cfg] # longer-than-normal reset delay -adapter_nsrst_delay 800 +adapter srst delay 800 reset_config trst_and_srst separate diff --git a/tcl/board/csb337.cfg b/tcl/board/csb337.cfg index 5e225f5f5..a9d013929 100644 --- a/tcl/board/csb337.cfg +++ b/tcl/board/csb337.cfg @@ -19,7 +19,7 @@ if { [info exists ETM_DRIVER] } { proc csb337_clk_init { } { # CPU is in Slow Clock Mode (32KiHz) ... needs slow JTAG clock - adapter_khz 8 + adapter speed 8 # CKGR_MOR: start main oscillator (3.6864 MHz) mww 0xfffffc20 0xff01 @@ -37,7 +37,7 @@ proc csb337_clk_init { } { sleep 20 # CPU is in Normal Mode ... allows faster JTAG clock speed - adapter_khz 40000 + adapter speed 40000 } proc csb337_nor_init { } { diff --git a/tcl/board/csb732.cfg b/tcl/board/csb732.cfg index 4d6f0e489..35e397ff2 100644 --- a/tcl/board/csb732.cfg +++ b/tcl/board/csb732.cfg @@ -3,7 +3,7 @@ source [find target/imx35.cfg] # Determined by trial and error reset_config trst_and_srst combined -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 200 $_TARGETNAME configure -event gdb-attach { reset init } diff --git a/tcl/board/digi_connectcore_wi-9c.cfg b/tcl/board/digi_connectcore_wi-9c.cfg index 8a8d4c3bf..43ad1c90e 100644 --- a/tcl/board/digi_connectcore_wi-9c.cfg +++ b/tcl/board/digi_connectcore_wi-9c.cfg @@ -36,7 +36,7 @@ if { [info exists CPUTAPID] } { set _TARGETNAME $_CHIPNAME.cpu jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 0 diff --git a/tcl/board/digilent_analog_discovery.cfg b/tcl/board/digilent_analog_discovery.cfg index 65eb66084..954e54008 100644 --- a/tcl/board/digilent_analog_discovery.cfg +++ b/tcl/board/digilent_analog_discovery.cfg @@ -13,6 +13,6 @@ ftdi_vid_pid 0x0403 0x6014 ftdi_layout_init 0x8008 0x800b -adapter_khz 25000 +adapter speed 25000 source [find cpld/xilinx-xc6s.cfg] diff --git a/tcl/board/dm365evm.cfg b/tcl/board/dm365evm.cfg index 8f268c455..ed34c4b29 100644 --- a/tcl/board/dm365evm.cfg +++ b/tcl/board/dm365evm.cfg @@ -103,7 +103,7 @@ proc dm365evm_init {} { echo "Initialize DM365 EVM board" # CLKIN = 24 MHz ... can't talk quickly to ARM yet - adapter_khz 1500 + adapter speed 1500 # FIXME -- PLL init diff --git a/tcl/board/dp_busblaster_v3.cfg b/tcl/board/dp_busblaster_v3.cfg index f21197b73..a9974d9bc 100644 --- a/tcl/board/dp_busblaster_v3.cfg +++ b/tcl/board/dp_busblaster_v3.cfg @@ -4,7 +4,7 @@ # http://dangerousprototypes.com/docs/Bus_Blaster # # To reprogram the on-board CPLD do: -# openocd -f board/dp_busblaster_v3.cfg -c "adapter_khz 1000; init; svf ; shutdown" +# openocd -f board/dp_busblaster_v3.cfg -c "adapter speed 1000; init; svf ; shutdown" # source [find interface/ftdi/dp_busblaster.cfg] diff --git a/tcl/board/efm32.cfg b/tcl/board/efm32.cfg index d2bc9a611..adbdda72e 100644 --- a/tcl/board/efm32.cfg +++ b/tcl/board/efm32.cfg @@ -5,7 +5,7 @@ source [find interface/jlink.cfg] transport select swd -adapter_khz 1000 +adapter speed 1000 set CHIPNAME efm32 source [find target/efm32.cfg] diff --git a/tcl/board/ek-lm3s1968.cfg b/tcl/board/ek-lm3s1968.cfg index 8d990b198..bbb04baa6 100644 --- a/tcl/board/ek-lm3s1968.cfg +++ b/tcl/board/ek-lm3s1968.cfg @@ -5,7 +5,7 @@ # # NOTE: to use J-Link instead of the on-board interface, -# you may also need to reduce adapter_khz to be about 1200. +# you may also need to reduce adapter speed to be about 1200. # source [find interface/jlink.cfg] # include the FT2232 interface config for on-board JTAG interface diff --git a/tcl/board/embedded-artists_lpc2478-32.cfg b/tcl/board/embedded-artists_lpc2478-32.cfg index b036cd69c..6c3aec648 100644 --- a/tcl/board/embedded-artists_lpc2478-32.cfg +++ b/tcl/board/embedded-artists_lpc2478-32.cfg @@ -15,7 +15,7 @@ proc read_register {register} { proc init_board {} { # Delays on reset lines - adapter_nsrst_delay 500 + adapter srst delay 500 jtag_ntrst_delay 1 # Adaptive JTAG clocking through RTCK. diff --git a/tcl/board/emcraft_imx8m-som-bsb.cfg b/tcl/board/emcraft_imx8m-som-bsb.cfg index 5571d0ecb..248c0d400 100644 --- a/tcl/board/emcraft_imx8m-som-bsb.cfg +++ b/tcl/board/emcraft_imx8m-som-bsb.cfg @@ -6,13 +6,13 @@ transport select jtag # set a safe JTAG clock speed, can be overridden -adapter_khz 1000 +adapter speed 1000 # SRST and TRST are wired up reset_config trst_and_srst # delay after SRST goes inactive -adapter_nsrst_delay 70 +adapter srst delay 70 # board has an i.MX8MQ with 4 Cortex-A53 cores set CHIPNAME imx8mq diff --git a/tcl/board/ethernut3.cfg b/tcl/board/ethernut3.cfg index ad4552733..72fc5ade3 100644 --- a/tcl/board/ethernut3.cfg +++ b/tcl/board/ethernut3.cfg @@ -20,13 +20,13 @@ flash bank $_FLASHNAME cfi 0x10000000 0x400000 2 2 $_TARGETNAME # Micrel MIC2775-29YM5 Supervisor # Reset output will remain active for 280ms (maximum) # -adapter_nsrst_delay 300 +adapter srst delay 300 jtag_ntrst_delay 300 arm7_9 fast_memory_access enable arm7_9 dcc_downloads enable -adapter_khz 16000 +adapter speed 16000 # Target events diff --git a/tcl/board/fsl_imx6q_sabresd.cfg b/tcl/board/fsl_imx6q_sabresd.cfg index e1f0892f0..cf34cd16d 100644 --- a/tcl/board/fsl_imx6q_sabresd.cfg +++ b/tcl/board/fsl_imx6q_sabresd.cfg @@ -13,7 +13,7 @@ transport select jtag # iMX6Q POR gates JTAG and the chip is completely incommunicado # over JTAG for at least 10ms after nSRST is deasserted -adapter_nsrst_delay 11 +adapter srst delay 11 # Source generic iMX6Q target configuration set CHIPNAME imx6q @@ -144,4 +144,4 @@ $_TARGETNAME.0 configure -event reset-assert { } # hook the init function into the reset-init event $_TARGETNAME.0 configure -event reset-init { imx6q_sabresd_init } # set a slow default JTAG clock, can be overridden later -adapter_khz 1000 +adapter speed 1000 diff --git a/tcl/board/glyn_tonga2.cfg b/tcl/board/glyn_tonga2.cfg index 17ed3cf20..31aa9ff5e 100644 --- a/tcl/board/glyn_tonga2.cfg +++ b/tcl/board/glyn_tonga2.cfg @@ -19,12 +19,12 @@ source [find target/tmpa900.cfg] # Initial JTAG speed should not exceed 1/6 of the initial CPU clock # frequency (24MHz). Be conservative and use 1/8 of the frequency. # (24MHz / 8 = 3MHz) -adapter_khz 3000 +adapter speed 3000 $_TARGETNAME configure -event reset-start { # Upon reset, set the JTAG frequency to 3MHz again, see above. echo "Setting JTAG speed to 3MHz until clocks are initialized." - adapter_khz 3000 + adapter speed 3000 # Halt the CPU. halt @@ -41,7 +41,7 @@ $_TARGETNAME configure -event reset-init { # Tests showed that 15MHz works OK, higher speeds can cause problems, # though. Not sure if this is a CPU issue or JTAG adapter issue. echo "Increasing JTAG speed to 15MHz." - adapter_khz 15000 + adapter speed 15000 # Enable faster memory access. arm7_9 fast_memory_access enable diff --git a/tcl/board/hilscher_nxdb500sys.cfg b/tcl/board/hilscher_nxdb500sys.cfg index 77073e729..d71c4453b 100644 --- a/tcl/board/hilscher_nxdb500sys.cfg +++ b/tcl/board/hilscher_nxdb500sys.cfg @@ -5,7 +5,7 @@ source [find target/hilscher_netx500.cfg] reset_config trst_and_srst -adapter_nsrst_delay 500 +adapter srst delay 500 jtag_ntrst_delay 500 $_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1 diff --git a/tcl/board/hilscher_nxeb500hmi.cfg b/tcl/board/hilscher_nxeb500hmi.cfg index 64391561e..aa3d58701 100644 --- a/tcl/board/hilscher_nxeb500hmi.cfg +++ b/tcl/board/hilscher_nxeb500hmi.cfg @@ -5,7 +5,7 @@ source [find target/hilscher_netx500.cfg] reset_config trst_and_srst -adapter_nsrst_delay 500 +adapter srst delay 500 jtag_ntrst_delay 500 $_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1 diff --git a/tcl/board/hilscher_nxhx10.cfg b/tcl/board/hilscher_nxhx10.cfg index 4ef2f3b96..7ff99165a 100644 --- a/tcl/board/hilscher_nxhx10.cfg +++ b/tcl/board/hilscher_nxhx10.cfg @@ -9,7 +9,7 @@ source [find target/hilscher_netx10.cfg] # problems try to line below # reset_config trst_and_srst srst_pulls_trst reset_config trst_and_srst -adapter_nsrst_delay 500 +adapter srst delay 500 jtag_ntrst_delay 500 $_TARGETNAME configure -work-area-virt 0x08000000 -work-area-phys 0x08000000 -work-area-size 0x4000 -work-area-backup 1 diff --git a/tcl/board/hilscher_nxhx50.cfg b/tcl/board/hilscher_nxhx50.cfg index eebb16524..0867f2ed6 100644 --- a/tcl/board/hilscher_nxhx50.cfg +++ b/tcl/board/hilscher_nxhx50.cfg @@ -5,7 +5,7 @@ source [find target/hilscher_netx50.cfg] reset_config trst_and_srst -adapter_nsrst_delay 500 +adapter srst delay 500 jtag_ntrst_delay 500 $_TARGETNAME configure -work-area-virt 0x10000000 -work-area-phys 0x10000000 -work-area-size 0x4000 -work-area-backup 1 diff --git a/tcl/board/hilscher_nxhx500.cfg b/tcl/board/hilscher_nxhx500.cfg index dd3a9514d..2ba030ec1 100644 --- a/tcl/board/hilscher_nxhx500.cfg +++ b/tcl/board/hilscher_nxhx500.cfg @@ -5,7 +5,7 @@ source [find target/hilscher_netx500.cfg] reset_config trst_and_srst -adapter_nsrst_delay 500 +adapter srst delay 500 jtag_ntrst_delay 500 $_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1 diff --git a/tcl/board/hilscher_nxsb100.cfg b/tcl/board/hilscher_nxsb100.cfg index efb091b10..807e29200 100644 --- a/tcl/board/hilscher_nxsb100.cfg +++ b/tcl/board/hilscher_nxsb100.cfg @@ -5,7 +5,7 @@ source [find target/hilscher_netx500.cfg] reset_config trst_and_srst -adapter_nsrst_delay 500 +adapter srst delay 500 jtag_ntrst_delay 500 $_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1 diff --git a/tcl/board/hitex_lpc1768stick.cfg b/tcl/board/hitex_lpc1768stick.cfg index 161e9654a..8c1193608 100644 --- a/tcl/board/hitex_lpc1768stick.cfg +++ b/tcl/board/hitex_lpc1768stick.cfg @@ -11,5 +11,5 @@ source [find target/lpc17xx.cfg] # startup @ 500kHz -adapter_khz 500 +adapter speed 500 diff --git a/tcl/board/hitex_lpc2929.cfg b/tcl/board/hitex_lpc2929.cfg index d2515371d..f51779867 100644 --- a/tcl/board/hitex_lpc2929.cfg +++ b/tcl/board/hitex_lpc2929.cfg @@ -2,12 +2,12 @@ # http://www.hitex.com/ # Delays on reset lines -adapter_nsrst_delay 50 +adapter srst delay 50 jtag_ntrst_delay 1 # Maximum of 1/8 of clock frequency (XTAL = 16 MHz). # Adaptive clocking through RTCK is not supported. -adapter_khz 2000 +adapter speed 2000 # Target device: LPC29xx with ETB # The following variables are used by the LPC2900 script: @@ -24,7 +24,7 @@ $_TARGETNAME configure -work-area-phys 0x58000000 -work-area-size 0x10000 -work- # Event handlers $_TARGETNAME configure -event reset-start { # Back to the slow JTAG clock - adapter_khz 2000 + adapter speed 2000 } # External 16-bit flash at chip select CS7 (SST39VF3201-70, 4 MiB) @@ -46,7 +46,7 @@ $_TARGETNAME configure -event reset-init { mww 0xFFFF8070 0x02000000 ;# SYS_CLK_CONF: PLL # Increase JTAG speed - adapter_khz 6000 + adapter speed 6000 # Enable external memory bus (16-bit SRAM at CS6, 16-bit flash at CS7) mww 0xE0001138 0x0000001F ;# P1.14 = D0 diff --git a/tcl/board/hitex_stm32-performancestick.cfg b/tcl/board/hitex_stm32-performancestick.cfg index 82fb16961..738178af0 100644 --- a/tcl/board/hitex_stm32-performancestick.cfg +++ b/tcl/board/hitex_stm32-performancestick.cfg @@ -12,5 +12,5 @@ source [find target/stm32f1x.cfg] jtag newtap str750 cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id 0x4f1f0041 # for some reason this board like to startup @ 500kHz -adapter_khz 500 +adapter speed 500 diff --git a/tcl/board/hitex_str9-comstick.cfg b/tcl/board/hitex_str9-comstick.cfg index be153314f..3b9225213 100644 --- a/tcl/board/hitex_str9-comstick.cfg +++ b/tcl/board/hitex_str9-comstick.cfg @@ -5,9 +5,9 @@ source [find interface/ftdi/hitex_str9-comstick.cfg] # set jtag speed -adapter_khz 3000 +adapter speed 3000 -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 #use combined on interfaces or targets that can't set TRST/SRST separately reset_config trst_and_srst diff --git a/tcl/board/icnova_imx53_sodimm.cfg b/tcl/board/icnova_imx53_sodimm.cfg index aa6a148a0..2345ef120 100644 --- a/tcl/board/icnova_imx53_sodimm.cfg +++ b/tcl/board/icnova_imx53_sodimm.cfg @@ -15,7 +15,7 @@ echo "i.MX53 SO-Dimm board lodaded." # Set reset type #reset_config srst_only -adapter_khz 3000 +adapter speed 3000 # Slow speed to be sure it will work jtag_rclk 1000 @@ -58,7 +58,7 @@ proc sodimm_init { } { arm core_state arm jtag_rclk 3000 -# adapter_khz 3000 +# adapter speed 3000 } diff --git a/tcl/board/icnova_sam9g45_sodimm.cfg b/tcl/board/icnova_sam9g45_sodimm.cfg index 84dab3899..bf70cca9a 100644 --- a/tcl/board/icnova_sam9g45_sodimm.cfg +++ b/tcl/board/icnova_sam9g45_sodimm.cfg @@ -15,7 +15,7 @@ source [find target/at91sam9g45.cfg] # Set reset type. # reset_config trst_and_srst -# adapter_nsrst_delay 200 +# adapter srst delay 200 # jtag_ntrst_delay 200 @@ -58,7 +58,7 @@ proc at91sam9g45_start { } { arm7_9 fast_memory_access disable # Slow-speed oscillator enabled at reset, so run jtag speed slow. - adapter_khz 4 + adapter speed 4 # Make sure processor is halted, or error will result in following steps. halt wait_halt 10000 @@ -117,7 +117,7 @@ proc at91sam9g45_init { } { # Switch over to adaptive clocking. - adapter_khz 6000 + adapter speed 6000 # Enable faster DCC downloads. diff --git a/tcl/board/imx27lnst.cfg b/tcl/board/imx27lnst.cfg index e0ed05794..ac5a9f3e6 100644 --- a/tcl/board/imx27lnst.cfg +++ b/tcl/board/imx27lnst.cfg @@ -8,7 +8,7 @@ proc imx27lnst_init { } { # This setup puts RAM at 0xA0000000 # reset the board correctly - adapter_khz 500 + adapter speed 500 reset run reset halt diff --git a/tcl/board/imx53-m53evk.cfg b/tcl/board/imx53-m53evk.cfg index eada27ab6..d18afc73a 100644 --- a/tcl/board/imx53-m53evk.cfg +++ b/tcl/board/imx53-m53evk.cfg @@ -18,7 +18,7 @@ echo "iMX53 M53EVK board lodaded." reset_config trst_and_srst separate trst_open_drain srst_open_drain # Run at 6 MHz -adapter_khz 6000 +adapter speed 6000 $_TARGETNAME configure -event "reset-assert" { echo "Reseting ...." diff --git a/tcl/board/imx53loco.cfg b/tcl/board/imx53loco.cfg index 06c399378..57473ead2 100644 --- a/tcl/board/imx53loco.cfg +++ b/tcl/board/imx53loco.cfg @@ -13,7 +13,7 @@ echo "iMX53 Loco board lodaded." # Set reset type #reset_config srst_only -adapter_khz 3000 +adapter speed 3000 # Slow speed to be sure it will work jtag_rclk 1000 @@ -59,7 +59,7 @@ proc loco_init { } { arm core_state arm jtag_rclk 3000 -# adapter_khz 3000 +# adapter speed 3000 } diff --git a/tcl/board/insignal_arndale.cfg b/tcl/board/insignal_arndale.cfg index 25c123e7b..09a7223f0 100644 --- a/tcl/board/insignal_arndale.cfg +++ b/tcl/board/insignal_arndale.cfg @@ -5,4 +5,4 @@ source [find target/exynos5250.cfg] # Experimentally determined highest working speed -adapter_khz 200 +adapter speed 200 diff --git a/tcl/board/kasli.cfg b/tcl/board/kasli.cfg index fb59f931f..06cc1e6c0 100644 --- a/tcl/board/kasli.cfg +++ b/tcl/board/kasli.cfg @@ -7,7 +7,7 @@ ftdi_layout_init 0x0008 0x000b reset_config none transport select jtag -adapter_khz 25000 +adapter speed 25000 source [find cpld/xilinx-xc7.cfg] source [find cpld/jtagspi.cfg] diff --git a/tcl/board/kc705.cfg b/tcl/board/kc705.cfg index e032e9b21..51ea14d46 100644 --- a/tcl/board/kc705.cfg +++ b/tcl/board/kc705.cfg @@ -5,7 +5,7 @@ source [find cpld/xilinx-xc7.cfg] source [find cpld/jtagspi.cfg] source [find fpga/xilinx-xadc.cfg] source [find fpga/xilinx-dna.cfg] -adapter_khz 25000 +adapter speed 25000 # example command to write bitstream, soft-cpu bios and runtime: # openocd -f board/kc705.cfg -c "init;\ diff --git a/tcl/board/kcu105.cfg b/tcl/board/kcu105.cfg index c8daea652..e2b68ca75 100644 --- a/tcl/board/kcu105.cfg +++ b/tcl/board/kcu105.cfg @@ -8,4 +8,4 @@ source [find cpld/xilinx-xcu.cfg] source [find cpld/jtagspi.cfg] -adapter_khz 25000 +adapter speed 25000 diff --git a/tcl/board/kindle2.cfg b/tcl/board/kindle2.cfg index f32b2a321..fbb1022fd 100644 --- a/tcl/board/kindle2.cfg +++ b/tcl/board/kindle2.cfg @@ -18,7 +18,7 @@ source [find target/imx31.cfg] source [find target/imx.cfg] $_TARGETNAME configure -event reset-init { kindle2_init } -$_TARGETNAME configure -event reset-start { adapter_khz 1000 } +$_TARGETNAME configure -event reset-start { adapter speed 1000 } # 8MiB NOR Flash set _FLASHNAME $_CHIPNAME.flash @@ -36,7 +36,7 @@ jtag_ntrst_delay 30 # this is broken but enabled by default arm11 memwrite burst disable -adapter_khz 1000 +adapter speed 1000 ftdi_tdo_sample_edge falling proc kindle2_init {} { diff --git a/tcl/board/lubbock.cfg b/tcl/board/lubbock.cfg index 298954cc0..d803e6fb2 100644 --- a/tcl/board/lubbock.cfg +++ b/tcl/board/lubbock.cfg @@ -4,7 +4,7 @@ source [find target/pxa255.cfg] -adapter_nsrst_delay 250 +adapter srst delay 250 jtag_ntrst_delay 250 # NOTE: until after pinmux and such are set up, only CS0 is diff --git a/tcl/board/marsohod.cfg b/tcl/board/marsohod.cfg index 681f575cc..b1393a914 100644 --- a/tcl/board/marsohod.cfg +++ b/tcl/board/marsohod.cfg @@ -6,7 +6,7 @@ # Recommended MBFTDI programmer source [find interface/ftdi/mbftdi.cfg] -adapter_khz 2000 +adapter speed 2000 transport select jtag # Altera MAXII EPM240T100C CPLD diff --git a/tcl/board/marsohod2.cfg b/tcl/board/marsohod2.cfg index d4897c3c3..31819a2f9 100644 --- a/tcl/board/marsohod2.cfg +++ b/tcl/board/marsohod2.cfg @@ -6,7 +6,7 @@ # Built-in MBFTDI programmer source [find interface/ftdi/mbftdi.cfg] -adapter_khz 2000 +adapter speed 2000 transport select jtag # Cyclone III EP3C10E144 FPGA diff --git a/tcl/board/marsohod3.cfg b/tcl/board/marsohod3.cfg index bb3c74f28..fa00706d3 100644 --- a/tcl/board/marsohod3.cfg +++ b/tcl/board/marsohod3.cfg @@ -6,7 +6,7 @@ # Built-in MBFTDI programmer source [find interface/ftdi/mbftdi.cfg] -adapter_khz 2000 +adapter speed 2000 transport select jtag # MAX10 10M50SAE144C8GES FPGA diff --git a/tcl/board/mcb1700.cfg b/tcl/board/mcb1700.cfg index 068a19b24..4954dab0a 100644 --- a/tcl/board/mcb1700.cfg +++ b/tcl/board/mcb1700.cfg @@ -11,7 +11,7 @@ set MCB1700_CCLK $CCLK $_TARGETNAME configure -event reset-start { # Start *real slow* as we do not know the # state the boot rom left the clock in - adapter_khz 10 + adapter speed 10 } # Set up 100MHz clock to CPU @@ -55,7 +55,7 @@ $_TARGETNAME configure -event reset-init { # # global MCB1700_CCLK - adapter_khz [expr $MCB1700_CCLK / 8] + adapter speed [expr $MCB1700_CCLK / 8] # Do not remap 0x0000-0x0020 to anything but the flash (i.e. select # "User Flash Mode" where interrupt vectors are _not_ remapped, diff --git a/tcl/board/microchip_saml11_xplained_pro.cfg b/tcl/board/microchip_saml11_xplained_pro.cfg index 3558a8e71..2ab61118f 100644 --- a/tcl/board/microchip_saml11_xplained_pro.cfg +++ b/tcl/board/microchip_saml11_xplained_pro.cfg @@ -4,7 +4,7 @@ # source [find interface/cmsis-dap.cfg] -adapter_khz 1000 +adapter speed 1000 set CHIPNAME saml11 source [find target/atsaml1x.cfg] diff --git a/tcl/board/mini2440.cfg b/tcl/board/mini2440.cfg index 874f829ab..9dca5a37c 100644 --- a/tcl/board/mini2440.cfg +++ b/tcl/board/mini2440.cfg @@ -111,7 +111,7 @@ target create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME $_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 1 #reset configuration -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 reset_config trst_and_srst @@ -120,7 +120,7 @@ reset_config trst_and_srst # IMPORTANT! See README at top of this file. #------------------------------------------------------------------------- - adapter_khz 12000 + adapter speed 12000 jtag interface #------------------------------------------------------------------------- @@ -140,7 +140,7 @@ reset_config trst_and_srst nand device s3c2440 0 - adapter_nsrst_delay 100 + adapter srst delay 100 jtag_ntrst_delay 100 reset_config trst_and_srst init diff --git a/tcl/board/mini6410.cfg b/tcl/board/mini6410.cfg index d00ce1f8c..2cee93935 100644 --- a/tcl/board/mini6410.cfg +++ b/tcl/board/mini6410.cfg @@ -88,8 +88,8 @@ proc init_6410_flash {} { } -adapter_khz 1000 -adapter_nsrst_delay 100 +adapter speed 1000 +adapter srst delay 100 jtag_ntrst_delay 100 reset_config trst_and_srst diff --git a/tcl/board/numato_mimas_a7.cfg b/tcl/board/numato_mimas_a7.cfg index a538872d1..d4012bada 100644 --- a/tcl/board/numato_mimas_a7.cfg +++ b/tcl/board/numato_mimas_a7.cfg @@ -30,7 +30,7 @@ ftdi_tdo_sample_edge falling # ftdi_layout_init 0x0008 0x004b reset_config none -adapter_khz 30000 +adapter speed 30000 source [find cpld/xilinx-xc7.cfg] source [find cpld/jtagspi.cfg] diff --git a/tcl/board/nxp_imx7sabre.cfg b/tcl/board/nxp_imx7sabre.cfg index 25b7b8781..c595e3a67 100644 --- a/tcl/board/nxp_imx7sabre.cfg +++ b/tcl/board/nxp_imx7sabre.cfg @@ -3,12 +3,12 @@ transport select jtag # set a safe speed, can be overridden -adapter_khz 1000 +adapter speed 1000 # reset configuration has TRST and SRST support reset_config trst_and_srst srst_push_pull # need at least 100ms delay after SRST release for JTAG -adapter_nsrst_delay 100 +adapter srst delay 100 # source the target file source [find target/imx7.cfg] diff --git a/tcl/board/nxp_mcimx8m-evk.cfg b/tcl/board/nxp_mcimx8m-evk.cfg index e2d63ce7c..dd9bd53ac 100644 --- a/tcl/board/nxp_mcimx8m-evk.cfg +++ b/tcl/board/nxp_mcimx8m-evk.cfg @@ -6,13 +6,13 @@ transport select jtag # set a safe JTAG clock speed, can be overridden -adapter_khz 1000 +adapter speed 1000 # default JTAG configuration has only SRST and no TRST reset_config srst_only srst_push_pull # delay after SRST goes inactive -adapter_nsrst_delay 70 +adapter srst delay 70 # board has an i.MX8MQ with 4 Cortex-A53 cores set CHIPNAME imx8mq diff --git a/tcl/board/olimex_sam7_la2.cfg b/tcl/board/olimex_sam7_la2.cfg index 89d2b5a59..038fe67b6 100644 --- a/tcl/board/olimex_sam7_la2.cfg +++ b/tcl/board/olimex_sam7_la2.cfg @@ -2,7 +2,7 @@ source [find target/at91sam7a2.cfg] # delays needed to get stable reads of cpu state jtag_ntrst_delay 10 -adapter_nsrst_delay 200 +adapter srst delay 200 # board uses pullup and connects only srst reset_config srst_open_drain @@ -10,9 +10,9 @@ reset_config srst_open_drain # srst is connected to NRESET of CPU and fully resets everything... reset_config srst_only srst_pulls_trst -adapter_khz 1 +adapter speed 1 $_TARGETNAME configure -event reset-start { - adapter_khz 1 + adapter speed 1 } $_TARGETNAME configure -event reset-init { @@ -61,7 +61,7 @@ $_TARGETNAME configure -event reset-init { echo "set up pll" sleep 100 - adapter_khz 5000 + adapter speed 5000 } $_TARGETNAME arm7_9 dcc_downloads enable diff --git a/tcl/board/openrd.cfg b/tcl/board/openrd.cfg index 7659b0749..696af4e5b 100644 --- a/tcl/board/openrd.cfg +++ b/tcl/board/openrd.cfg @@ -3,7 +3,7 @@ source [find interface/ftdi/openrd.cfg] source [find target/feroceon.cfg] -adapter_khz 2000 +adapter speed 2000 $_TARGETNAME configure \ -work-area-phys 0x10000000 \ diff --git a/tcl/board/or1k_generic.cfg b/tcl/board/or1k_generic.cfg index c543ebe25..7c1956563 100644 --- a/tcl/board/or1k_generic.cfg +++ b/tcl/board/or1k_generic.cfg @@ -17,7 +17,7 @@ source [find target/or1k.cfg] poll_period 1 # Set the adapter speed -adapter_khz 3000 +adapter speed 3000 # Enable the target description feature gdb_target_description enable diff --git a/tcl/board/phytec_lpc3250.cfg b/tcl/board/phytec_lpc3250.cfg index 6a7e8e923..1c48f5df7 100644 --- a/tcl/board/phytec_lpc3250.cfg +++ b/tcl/board/phytec_lpc3250.cfg @@ -1,8 +1,8 @@ source [find target/lpc3250.cfg] -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 1 -adapter_khz 200 +adapter speed 200 reset_config trst_and_srst separate arm7_9 dcc_downloads enable @@ -11,11 +11,11 @@ $_TARGETNAME configure -event gdb-attach { reset init } $_TARGETNAME configure -event reset-start { arm7_9 fast_memory_access disable - adapter_khz 200 + adapter speed 200 } $_TARGETNAME configure -event reset-end { - adapter_khz 6000 + adapter speed 6000 arm7_9 fast_memory_access enable } diff --git a/tcl/board/pxa255_sst.cfg b/tcl/board/pxa255_sst.cfg index 49cad5db7..2b44a0541 100644 --- a/tcl/board/pxa255_sst.cfg +++ b/tcl/board/pxa255_sst.cfg @@ -93,7 +93,7 @@ $_TARGETNAME configure -event reset-init {pxa255_sst_init} reset_config trst_and_srst -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 200 #xscale debug_handler 0 0xFFFF0800 ;# debug handler base address diff --git a/tcl/board/quark_d2000_refboard.cfg b/tcl/board/quark_d2000_refboard.cfg index 460e8c969..8b8314a0e 100644 --- a/tcl/board/quark_d2000_refboard.cfg +++ b/tcl/board/quark_d2000_refboard.cfg @@ -10,6 +10,6 @@ ftdi_layout_signal nTRST -data 0x0100 -noe 0x0100 source [find target/quark_d20xx.cfg] -adapter_khz 1000 +adapter speed 1000 reset_config trst_only diff --git a/tcl/board/quark_x10xx_board.cfg b/tcl/board/quark_x10xx_board.cfg index 8dc600b80..4ecf30ed8 100644 --- a/tcl/board/quark_x10xx_board.cfg +++ b/tcl/board/quark_x10xx_board.cfg @@ -4,6 +4,6 @@ source [find target/quark_x10xx.cfg] #default frequency but this can be adjusted at runtime -adapter_khz 4000 +adapter speed 4000 reset_config trst_only diff --git a/tcl/board/rsc-w910.cfg b/tcl/board/rsc-w910.cfg index 636a05399..cb1733b27 100644 --- a/tcl/board/rsc-w910.cfg +++ b/tcl/board/rsc-w910.cfg @@ -12,8 +12,8 @@ source [find target/nuc910.cfg] # reset_config trst_and_srst srst_pulls_trst -adapter_khz 1000 -adapter_nsrst_delay 100 +adapter speed 1000 +adapter srst delay 100 jtag_ntrst_delay 100 $_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x04000000 -work-area-backup 0 @@ -28,7 +28,7 @@ nand device $_NANDNAME nuc910 $_TARGETNAME # Target events # -$_TARGETNAME configure -event reset-start {adapter_khz 1000} +$_TARGETNAME configure -event reset-start {adapter speed 1000} $_TARGETNAME configure -event reset-init { # switch on PLL for 200MHz operation @@ -47,7 +47,7 @@ $_TARGETNAME configure -event reset-init { arm7_9 dcc_downloads enable arm7_9 fast_memory_access enable - adapter_khz 15000 + adapter speed 15000 # map nor flash to 0x20000000 # map sdram to 0x00000000 diff --git a/tcl/board/sayma_amc.cfg b/tcl/board/sayma_amc.cfg index 0b507ee0e..009eb78c2 100644 --- a/tcl/board/sayma_amc.cfg +++ b/tcl/board/sayma_amc.cfg @@ -26,7 +26,7 @@ ftdi_layout_init 0x0098 0x008b #ftdi_layout_signal nTRST -data 0x0010 reset_config none -adapter_khz 5000 +adapter speed 5000 transport select jtag diff --git a/tcl/board/sheevaplug.cfg b/tcl/board/sheevaplug.cfg index 0d21be37c..7ccb88410 100644 --- a/tcl/board/sheevaplug.cfg +++ b/tcl/board/sheevaplug.cfg @@ -3,7 +3,7 @@ source [find interface/ftdi/sheevaplug.cfg] source [find target/feroceon.cfg] -adapter_khz 2000 +adapter speed 2000 $_TARGETNAME configure \ -work-area-phys 0x10000000 \ diff --git a/tcl/board/sifive-e31arty.cfg b/tcl/board/sifive-e31arty.cfg index ec10b27c3..b7a255ea2 100644 --- a/tcl/board/sifive-e31arty.cfg +++ b/tcl/board/sifive-e31arty.cfg @@ -1,7 +1,7 @@ # # Be sure you include the speed and interface before this file # Example: -# -c "adapter_khz 5000" -f "interface/ftdi/olimex-arm-usb-tiny-h.cfg" -f "board/sifive-e31arty.cfg" +# -c "adapter speed 5000" -f "interface/ftdi/olimex-arm-usb-tiny-h.cfg" -f "board/sifive-e31arty.cfg" set _CHIPNAME riscv jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001 diff --git a/tcl/board/sifive-e51arty.cfg b/tcl/board/sifive-e51arty.cfg index ffd83a058..20ad57551 100644 --- a/tcl/board/sifive-e51arty.cfg +++ b/tcl/board/sifive-e51arty.cfg @@ -1,7 +1,7 @@ # # Be sure you include the speed and interface before this file # Example: -# -c "adapter_khz 5000" -f "interface/ftdi/olimex-arm-usb-tiny-h.cfg" -f "board/sifive-e51arty.cfg" +# -c "adapter speed 5000" -f "interface/ftdi/olimex-arm-usb-tiny-h.cfg" -f "board/sifive-e51arty.cfg" set _CHIPNAME riscv jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001 diff --git a/tcl/board/sifive-hifive1.cfg b/tcl/board/sifive-hifive1.cfg index 9e62bbd04..196f540bb 100644 --- a/tcl/board/sifive-hifive1.cfg +++ b/tcl/board/sifive-hifive1.cfg @@ -1,4 +1,4 @@ -adapter_khz 10000 +adapter speed 10000 adapter driver ftdi ftdi_device_desc "Dual RS232-HS" @@ -10,7 +10,7 @@ ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020 #Reset Stretcher logic on FE310 is ~1 second long #This doesn't apply if you use # ftdi_set_signal, but still good to document -#adapter_nsrst_delay 1500 +#adapter srst delay 1500 set _CHIPNAME riscv jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 diff --git a/tcl/board/telo.cfg b/tcl/board/telo.cfg index 1d3afdf0b..05644f658 100644 --- a/tcl/board/telo.cfg +++ b/tcl/board/telo.cfg @@ -10,10 +10,10 @@ source [find target/c100helper.tcl] # Telo board & C100 support trst and srst # make the reset asserted to # allow RC circuit to discharge for: [ms] -adapter_nsrst_assert_width 100 +adapter srst pulse_width 100 jtag_ntrst_assert_width 100 # don't talk to JTAG after reset for: [ms] -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 reset_config trst_and_srst separate @@ -23,11 +23,11 @@ reset_config trst_and_srst separate # issue telnet: reset init # issue gdb: monitor reset init $_TARGETNAME configure -event reset-init { - adapter_khz 100 + adapter speed 100 # this will setup Telo board setupTelo #turn up the JTAG speed - adapter_khz 3000 + adapter speed 3000 echo "JTAG speek now 3MHz" echo "type helpC100 to get help on C100" } diff --git a/tcl/board/ti_am437x_idk.cfg b/tcl/board/ti_am437x_idk.cfg index 65e2094e8..fc2b81b29 100644 --- a/tcl/board/ti_am437x_idk.cfg +++ b/tcl/board/ti_am437x_idk.cfg @@ -4,7 +4,7 @@ source [find interface/ftdi/xds100v2.cfg] transport select jtag -adapter_khz 30000 +adapter speed 30000 source [find target/am437x.cfg] $_TARGETNAME configure -event reset-init { init_platform 0x61a11b32 } diff --git a/tcl/board/ti_am43xx_evm.cfg b/tcl/board/ti_am43xx_evm.cfg index d536314ba..dbc37ae82 100644 --- a/tcl/board/ti_am43xx_evm.cfg +++ b/tcl/board/ti_am43xx_evm.cfg @@ -1,6 +1,6 @@ # Works on both AM437x GP EVM and AM438x ePOS EVM transport select jtag -adapter_khz 16000 +adapter speed 16000 source [find target/am437x.cfg] diff --git a/tcl/board/ti_beaglebone.cfg b/tcl/board/ti_beaglebone.cfg index a54ad6275..6a6272d2d 100644 --- a/tcl/board/ti_beaglebone.cfg +++ b/tcl/board/ti_beaglebone.cfg @@ -4,7 +4,7 @@ # The JTAG interface is built directly on the board. source [find interface/ftdi/xds100v2.cfg] -adapter_khz 16000 +adapter speed 16000 reset_config trst_and_srst diff --git a/tcl/board/ti_beaglebone_black.cfg b/tcl/board/ti_beaglebone_black.cfg index 79fc1e8a8..c730814cc 100644 --- a/tcl/board/ti_beaglebone_black.cfg +++ b/tcl/board/ti_beaglebone_black.cfg @@ -1,7 +1,7 @@ # AM335x Beaglebone Black # http://beagleboard.org/bone -adapter_khz 1000 +adapter speed 1000 reset_config trst_and_srst diff --git a/tcl/board/ti_cc13x0_launchpad.cfg b/tcl/board/ti_cc13x0_launchpad.cfg index 9e1c1ea37..d2d0c68fe 100644 --- a/tcl/board/ti_cc13x0_launchpad.cfg +++ b/tcl/board/ti_cc13x0_launchpad.cfg @@ -3,5 +3,5 @@ # source [find interface/xds110.cfg] transport select jtag -adapter_khz 2500 +adapter speed 2500 source [find target/ti_cc13x0.cfg] diff --git a/tcl/board/ti_cc13x2_launchpad.cfg b/tcl/board/ti_cc13x2_launchpad.cfg index 18c5ce51c..706bb728a 100644 --- a/tcl/board/ti_cc13x2_launchpad.cfg +++ b/tcl/board/ti_cc13x2_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC13x2 LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter_khz 2500 +adapter speed 2500 transport select jtag source [find target/ti_cc13x2.cfg] diff --git a/tcl/board/ti_cc26x0_launchpad.cfg b/tcl/board/ti_cc26x0_launchpad.cfg index 3613a47f7..c16fa4c56 100644 --- a/tcl/board/ti_cc26x0_launchpad.cfg +++ b/tcl/board/ti_cc26x0_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC26x0 LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter_khz 2500 +adapter speed 2500 transport select jtag source [find target/ti_cc26x0.cfg] diff --git a/tcl/board/ti_cc26x2_launchpad.cfg b/tcl/board/ti_cc26x2_launchpad.cfg index 2f2b34b4b..e7941914c 100644 --- a/tcl/board/ti_cc26x2_launchpad.cfg +++ b/tcl/board/ti_cc26x2_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC26x2 LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter_khz 2500 +adapter speed 2500 transport select jtag source [find target/ti_cc26x2.cfg] diff --git a/tcl/board/ti_cc3200_launchxl.cfg b/tcl/board/ti_cc3200_launchxl.cfg index b78b09b7c..34f9bffb8 100644 --- a/tcl/board/ti_cc3200_launchxl.cfg +++ b/tcl/board/ti_cc3200_launchxl.cfg @@ -12,7 +12,7 @@ if { [info exists TRANSPORT] } { transport select jtag } -adapter_khz 2500 +adapter speed 2500 set WORKAREASIZE 0x40000 source [find target/ti_cc32xx.cfg] diff --git a/tcl/board/ti_cc3220sf_launchpad.cfg b/tcl/board/ti_cc3220sf_launchpad.cfg index a3dac620d..30255c793 100644 --- a/tcl/board/ti_cc3220sf_launchpad.cfg +++ b/tcl/board/ti_cc3220sf_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC3220SF-LaunchXL LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter_khz 2500 +adapter speed 2500 transport select swd source [find target/ti_cc3220sf.cfg] diff --git a/tcl/board/ti_cc32xx_launchpad.cfg b/tcl/board/ti_cc32xx_launchpad.cfg index f657bdfdb..6676e5d6e 100644 --- a/tcl/board/ti_cc32xx_launchpad.cfg +++ b/tcl/board/ti_cc32xx_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC32xx-LaunchXL LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter_khz 2500 +adapter speed 2500 transport select swd source [find target/ti_cc32xx.cfg] diff --git a/tcl/board/ti_msp432_launchpad.cfg b/tcl/board/ti_msp432_launchpad.cfg index bfad32235..f7c96eed1 100644 --- a/tcl/board/ti_msp432_launchpad.cfg +++ b/tcl/board/ti_msp432_launchpad.cfg @@ -2,6 +2,6 @@ # TI MSP432 LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter_khz 2500 +adapter speed 2500 transport select swd source [find target/ti_msp432.cfg] diff --git a/tcl/board/ti_tmdx570ls31usb.cfg b/tcl/board/ti_tmdx570ls31usb.cfg index 550244429..6d7350297 100644 --- a/tcl/board/ti_tmdx570ls31usb.cfg +++ b/tcl/board/ti_tmdx570ls31usb.cfg @@ -1,4 +1,4 @@ -adapter_khz 1500 +adapter speed 1500 source [find interface/ftdi/xds100v2.cfg] source [find target/ti_tms570.cfg] diff --git a/tcl/board/tocoding_poplar.cfg b/tcl/board/tocoding_poplar.cfg index d8b833004..d0951ce64 100644 --- a/tcl/board/tocoding_poplar.cfg +++ b/tcl/board/tocoding_poplar.cfg @@ -5,7 +5,7 @@ # board does not feature anything but JTAG transport select jtag -adapter_khz 10000 +adapter speed 10000 # SRST-only reset configuration reset_config srst_only srst_push_pull diff --git a/tcl/board/topas910.cfg b/tcl/board/topas910.cfg index 90c18c484..77084a96d 100644 --- a/tcl/board/topas910.cfg +++ b/tcl/board/topas910.cfg @@ -99,7 +99,7 @@ proc topas910_init { } { mww 0xf4300004 0x00000000 sleep 10 -# adapter_khz NNNN +# adapter speed NNNN # remap off in case of IROM boot mww 0xf0000004 0x00000001 diff --git a/tcl/board/topasa900.cfg b/tcl/board/topasa900.cfg index 2a388d511..91ee5847a 100644 --- a/tcl/board/topasa900.cfg +++ b/tcl/board/topasa900.cfg @@ -105,7 +105,7 @@ proc topasa900_init { } { mww 0xf4300004 0x00000000 sleep 10 -# adapter_khz NNNN +# adapter speed NNNN # remap off in case of IROM boot mww 0xf0000004 0x00000001 diff --git a/tcl/board/twr-vf65gs10.cfg b/tcl/board/twr-vf65gs10.cfg index a80407f38..0d6d3329a 100644 --- a/tcl/board/twr-vf65gs10.cfg +++ b/tcl/board/twr-vf65gs10.cfg @@ -198,4 +198,4 @@ proc board_init { } { # hook the init function into the reset-init event ${_TARGETNAME}0 configure -event reset-init { board_init } # set a slow default JTAG clock, can be overridden later -adapter_khz 1000 +adapter speed 1000 diff --git a/tcl/board/verdex.cfg b/tcl/board/verdex.cfg index 6da987528..dd267fcbe 100644 --- a/tcl/board/verdex.cfg +++ b/tcl/board/verdex.cfg @@ -8,7 +8,7 @@ source [find target/pxa270.cfg] reset_config trst_and_srst separate # XM4 = 400MHz, XL6P = 600MHz...let's run at 0.1*400MHz=40MHz -adapter_khz 40000 +adapter speed 40000 # flash bank # XL6P has 32 MB flash diff --git a/tcl/board/voltcraft_dso-3062c.cfg b/tcl/board/voltcraft_dso-3062c.cfg index 01e37e9a4..01879b128 100644 --- a/tcl/board/voltcraft_dso-3062c.cfg +++ b/tcl/board/voltcraft_dso-3062c.cfg @@ -13,7 +13,7 @@ source [find target/samsung_s3c2440.cfg] -adapter_khz 16000 +adapter speed 16000 # Samsung K9F1208U0C NAND flash chip (64MiB, 3.3V, 8-bit) nand device $_CHIPNAME.nand s3c2440 $_TARGETNAME diff --git a/tcl/board/zy1000.cfg b/tcl/board/zy1000.cfg index 57deaa837..e0d1ccf84 100644 --- a/tcl/board/zy1000.cfg +++ b/tcl/board/zy1000.cfg @@ -72,7 +72,7 @@ $_TARGETNAME configure -event gdb-attach { # other things than flash programming. $_TARGETNAME configure -work-area-phys 0x00020000 -work-area-size 0x20000 -work-area-backup 0 -adapter_khz 16000 +adapter speed 16000 proc production_info {} { diff --git a/tcl/interface/calao-usb-a9260.cfg b/tcl/interface/calao-usb-a9260.cfg index 5fae2f3b3..d1dc736da 100644 --- a/tcl/interface/calao-usb-a9260.cfg +++ b/tcl/interface/calao-usb-a9260.cfg @@ -6,6 +6,6 @@ # See calao-usb-a9260-c01.cfg and calao-usb-a9260-c02.cfg. # -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 200 diff --git a/tcl/interface/ft232r.cfg b/tcl/interface/ft232r.cfg index 24e338ff3..2c705c335 100644 --- a/tcl/interface/ft232r.cfg +++ b/tcl/interface/ft232r.cfg @@ -1,2 +1,2 @@ adapter driver ft232r -adapter_khz 1000 +adapter speed 1000 diff --git a/tcl/interface/ftdi/minispartan6.cfg b/tcl/interface/ftdi/minispartan6.cfg index 92aebbcfd..97a6abe04 100644 --- a/tcl/interface/ftdi/minispartan6.cfg +++ b/tcl/interface/ftdi/minispartan6.cfg @@ -12,4 +12,4 @@ ftdi_layout_init 0x0008 0x000b reset_config none # this generally works fast: the fpga can handle 30MHz, the spi flash can handle # 54MHz with simple read, no dummy cycles, and wait-for-write-completion -adapter_khz 30000 +adapter speed 30000 diff --git a/tcl/interface/ftdi/pipistrello.cfg b/tcl/interface/ftdi/pipistrello.cfg index 4e392942a..2074924a3 100644 --- a/tcl/interface/ftdi/pipistrello.cfg +++ b/tcl/interface/ftdi/pipistrello.cfg @@ -10,4 +10,4 @@ ftdi_layout_init 0x0008 0x000b reset_config none # this generally works fast: the fpga can handle 30MHz, the spi flash can handle # 54MHz with simple read, no dummy cycles, and wait-for-write-completion -adapter_khz 10000 +adapter speed 10000 diff --git a/tcl/interface/nds32-aice.cfg b/tcl/interface/nds32-aice.cfg index 8f32c899c..3b21025b5 100644 --- a/tcl/interface/nds32-aice.cfg +++ b/tcl/interface/nds32-aice.cfg @@ -10,6 +10,6 @@ aice serial "C001-42163" aice vid_pid 0x1CFC 0x0000 aice port aice_usb reset_config trst_and_srst -adapter_khz 24000 +adapter speed 24000 aice retry_times 50 aice count_to_check_dbger 30 diff --git a/tcl/target/1986ве1т.cfg b/tcl/target/1986ве1т.cfg index ecb3f8ae1..b7c9d6331 100644 --- a/tcl/target/1986ве1т.cfg +++ b/tcl/target/1986ве1т.cfg @@ -50,9 +50,9 @@ if { [info exists IMEMORY] && [string equal $IMEMORY true] } { } # JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -adapter_khz 1000 +adapter speed 1000 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } diff --git a/tcl/target/aduc702x.cfg b/tcl/target/aduc702x.cfg index fca0a7f96..9c756be3f 100644 --- a/tcl/target/aduc702x.cfg +++ b/tcl/target/aduc702x.cfg @@ -17,7 +17,7 @@ if { [info exists CPUTAPID] } { set _CPUTAPID 0x3f0f0f0f } -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 200 ## JTAG scan chain diff --git a/tcl/target/aducm360.cfg b/tcl/target/aducm360.cfg index ca4bc68de..caee9654e 100755 --- a/tcl/target/aducm360.cfg +++ b/tcl/target/aducm360.cfg @@ -36,7 +36,7 @@ swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPU dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu # SWD/JTAG speed -adapter_khz 1000 +adapter speed 1000 ## ## Target configuration @@ -51,6 +51,6 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME aducm360 0x00 0 0 0 $_TARGETNAME -adapter_nsrst_delay 100 +adapter srst delay 100 cortex_m reset_config sysresetreq diff --git a/tcl/target/allwinner_v3s.cfg b/tcl/target/allwinner_v3s.cfg index 32fd18872..d8d78bdc7 100644 --- a/tcl/target/allwinner_v3s.cfg +++ b/tcl/target/allwinner_v3s.cfg @@ -34,7 +34,7 @@ # 0220ms JTAG pins switched to SD mode # # The time frame of 20ms can be not enough to init and halt the CPU. In this -# case I would recommend to set: "adapter_khz 15000" +# case I would recommend to set: "adapter speed 15000" # To get more or less precise timings, the board should provide reset pin, # or some bench power supply with remote function. In my case I used # EEZ H24005 with this command to power on and halt the target: diff --git a/tcl/target/altera_fpgasoc.cfg b/tcl/target/altera_fpgasoc.cfg index 9a83b5ccb..0fc8d6735 100644 --- a/tcl/target/altera_fpgasoc.cfg +++ b/tcl/target/altera_fpgasoc.cfg @@ -36,7 +36,7 @@ jtag newtap $_CHIPNAME.fpga tap -irlen 10 -ircapture 0x01 -irmask 0x3 -expected- # core 1 - 0x80112000 # Slow speed to be sure it will work -adapter_khz 1000 +adapter speed 1000 set _TARGETNAME1 $_CHIPNAME.cpu.0 set _TARGETNAME2 $_CHIPNAME.cpu.1 @@ -46,7 +46,7 @@ dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu target create $_TARGETNAME1 cortex_a -dap $_CHIPNAME.dap \ -coreid 0 -dbgbase 0x80110000 -$_TARGETNAME1 configure -event reset-start { adapter_khz 1000 } +$_TARGETNAME1 configure -event reset-start { adapter speed 1000 } $_TARGETNAME1 configure -event reset-assert-post "cycv_dbginit $_TARGETNAME1" @@ -54,7 +54,7 @@ $_TARGETNAME1 configure -event reset-assert-post "cycv_dbginit $_TARGETNAME1" #target create $_TARGETNAME2 cortex_a -dap $_CHIPNAME.dap \ # -coreid 1 -dbgbase 0x80112000 -#$_TARGETNAME2 configure -event reset-start { adapter_khz 1000 } +#$_TARGETNAME2 configure -event reset-start { adapter speed 1000 } #$_TARGETNAME2 configure -event reset-assert-post "cycv_dbginit $_TARGETNAME2" proc cycv_dbginit {target} { diff --git a/tcl/target/amdm37x.cfg b/tcl/target/amdm37x.cfg index 5c4e3151d..7098adfa3 100644 --- a/tcl/target/amdm37x.cfg +++ b/tcl/target/amdm37x.cfg @@ -45,7 +45,7 @@ if { [info exists CHIPTYPE] } { # Run the adapter at the fastest acceptable speed with the slowest possible # core clock. -adapter_khz 10 +adapter speed 10 ############################################################################### # JTAG setup @@ -157,7 +157,7 @@ $_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000 # slowest possible core clock (16.8MHz/2 = 8.4MHz). It is OK to speed up # *after* PLL and clock tree setup. -$_TARGETNAME configure -event "reset-start" { adapter_khz 10 } +$_TARGETNAME configure -event "reset-start" { adapter speed 10 } # Describe the reset assert process for openocd - this is asserted with the # ICEPick @@ -176,7 +176,7 @@ $_TARGETNAME configure -event reset-assert-post { global _TARGETNAME amdm37x_dbginit $_TARGETNAME - adapter_khz 1000 + adapter speed 1000 } $_TARGETNAME configure -event gdb-attach { diff --git a/tcl/target/ar71xx.cfg b/tcl/target/ar71xx.cfg index 196b04868..0c64a96e0 100644 --- a/tcl/target/ar71xx.cfg +++ b/tcl/target/ar71xx.cfg @@ -1,7 +1,7 @@ # Atheros AR71xx MIPS 24Kc SoC. # tested on PB44 refererence board -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 reset_config trst_and_srst diff --git a/tcl/target/at91sam3XXX.cfg b/tcl/target/at91sam3XXX.cfg index e7dec4b3e..7d01ccdb0 100644 --- a/tcl/target/at91sam3XXX.cfg +++ b/tcl/target/at91sam3XXX.cfg @@ -74,9 +74,9 @@ $_TARGETNAME configure -event gdb-flash-erase-start { # running off a crystal, we can run closer to the limit. Note # that there can be a pretty wide band where things are more or less stable. -adapter_khz 500 +adapter speed 500 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } diff --git a/tcl/target/at91sam4XXX.cfg b/tcl/target/at91sam4XXX.cfg index ff7367040..ebb7eed3e 100644 --- a/tcl/target/at91sam4XXX.cfg +++ b/tcl/target/at91sam4XXX.cfg @@ -50,9 +50,9 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE # running off a crystal, we can run closer to the limit. Note # that there can be a pretty wide band where things are more or less stable. -adapter_khz 500 +adapter speed 500 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } diff --git a/tcl/target/at91sam4lXX.cfg b/tcl/target/at91sam4lXX.cfg index 4aee7d081..b73babcbb 100644 --- a/tcl/target/at91sam4lXX.cfg +++ b/tcl/target/at91sam4lXX.cfg @@ -21,7 +21,7 @@ reset_config srst_gates_jtag # Datasheet does not specify SYSCLK to JTAG/SWD clock ratio. # Usually used SYSCLK/6 is hell slow, testing shows that debugging can work @ SYSCLK/2 # but your mileage may vary. -adapter_khz 50 +adapter speed 50 # System RC oscillator RCSYS starts in 3 cycles -adapter_nsrst_delay 0 +adapter srst delay 0 diff --git a/tcl/target/at91sam9.cfg b/tcl/target/at91sam9.cfg index bf99fb2fa..e0ea31617 100644 --- a/tcl/target/at91sam9.cfg +++ b/tcl/target/at91sam9.cfg @@ -24,10 +24,10 @@ reset_config trst_and_srst separate trst_push_pull srst_open_drain jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID -adapter_nsrst_delay 300 +adapter srst delay 300 jtag_ntrst_delay 200 -adapter_khz 3 +adapter speed 3 ###################### # Target configuration diff --git a/tcl/target/at91sam9260_ext_RAM_ext_flash.cfg b/tcl/target/at91sam9260_ext_RAM_ext_flash.cfg index 9ab740904..3e4b7d76b 100644 --- a/tcl/target/at91sam9260_ext_RAM_ext_flash.cfg +++ b/tcl/target/at91sam9260_ext_RAM_ext_flash.cfg @@ -6,15 +6,15 @@ source [find target/at91sam9261.cfg] reset_config trst_and_srst -adapter_khz 4 +adapter speed 4 -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 200 scan_chain $_TARGETNAME configure -event reset-start { # at reset chip runs at 32khz - adapter_khz 8 + adapter speed 8 } $_TARGETNAME configure -event reset-init {at91sam_init} @@ -46,7 +46,7 @@ proc at91sam_init { } { sleep 10 ;# wait 10 ms # Now run at anything fast... ie: 10mhz! - adapter_khz 10000 ;# Increase JTAG Speed to 6 MHz + adapter speed 10000 ;# Increase JTAG Speed to 6 MHz mww 0xffffec00 0x0a0a0a0a ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit mww 0xffffec04 0x0b0b0b0b ;# SMC_PULSE0 diff --git a/tcl/target/at91sam9g20.cfg b/tcl/target/at91sam9g20.cfg index 3f5e3c626..6e45df20a 100644 --- a/tcl/target/at91sam9g20.cfg +++ b/tcl/target/at91sam9g20.cfg @@ -12,7 +12,7 @@ source [find target/at91sam9.cfg] # Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock). -adapter_khz 5 +adapter speed 5 # Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc. The # AT91SAM9G20 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000. diff --git a/tcl/target/at91samdXX.cfg b/tcl/target/at91samdXX.cfg index f0644d177..9a396fa13 100644 --- a/tcl/target/at91samdXX.cfg +++ b/tcl/target/at91samdXX.cfg @@ -66,12 +66,12 @@ reset_config srst_gates_jtag # This limit is most probably imposed by incorrectly handled SWD WAIT # on some SWD adapters. -adapter_khz 400 +adapter speed 400 # Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works # without problem at maximal clock speed. Atmel recommends # adapter speed less than 10 * CPU clock. -# adapter_khz 5000 +# adapter speed 5000 if {![using_hla]} { # if srst is not fitted use SYSRESETREQ to diff --git a/tcl/target/atheros_ar9331.cfg b/tcl/target/atheros_ar9331.cfg index bea37ed3c..6ab238c88 100644 --- a/tcl/target/atheros_ar9331.cfg +++ b/tcl/target/atheros_ar9331.cfg @@ -41,12 +41,12 @@ reset_config none srst_pulls_trst # For SRST based variant we still need proper timings. # For ETH part the reset should be asserted at least for 10ms # Since there is no other information let's take 100ms to be sure. -adapter_nsrst_assert_width 100 +adapter srst pulse_width 100 # according to the SoC documentation it should take at least 5ms from # reset end till bootstrap end. In the practice we need 8ms to get JTAG back # to live. -adapter_nsrst_delay 8 +adapter srst delay 8 if { [info exists CHIPNAME] } { set _CHIPNAME $_CHIPNAME diff --git a/tcl/target/atmega128.cfg b/tcl/target/atmega128.cfg index b8f7d0175..07161d572 100644 --- a/tcl/target/atmega128.cfg +++ b/tcl/target/atmega128.cfg @@ -4,10 +4,10 @@ set _ENDIAN little # jtag speed -adapter_khz 4500 +adapter speed 4500 reset_config srst_only -adapter_nsrst_delay 100 +adapter srst delay 100 #jtag scan chain if { [info exists CPUTAPID] } { @@ -27,7 +27,7 @@ flash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME #to use it, script will be like: #init -#adapter_khz 4500 +#adapter speed 4500 #reset init #verify_ircapture disable # diff --git a/tcl/target/atmega128rfa1.cfg b/tcl/target/atmega128rfa1.cfg index 2c12a6109..cda439d77 100644 --- a/tcl/target/atmega128rfa1.cfg +++ b/tcl/target/atmega128rfa1.cfg @@ -2,7 +2,7 @@ set _CHIPNAME avr set _ENDIAN little # jtag speed -adapter_khz 4500 +adapter speed 4500 # avr jtag docs never connect RSTN reset_config none diff --git a/tcl/target/atsame5x.cfg b/tcl/target/atsame5x.cfg index 61949cf5a..351a2ca2c 100644 --- a/tcl/target/atsame5x.cfg +++ b/tcl/target/atsame5x.cfg @@ -63,7 +63,7 @@ reset_config srst_gates_jtag # Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works # without problem at clock speed over 5000 khz. Atmel recommends # adapter speed less than 10 * CPU clock. -adapter_khz 2000 +adapter speed 2000 if {![using_hla]} { # if srst is not fitted use SYSRESETREQ to diff --git a/tcl/target/atsamv.cfg b/tcl/target/atsamv.cfg index 43962de31..4c136ead2 100644 --- a/tcl/target/atsamv.cfg +++ b/tcl/target/atsamv.cfg @@ -39,7 +39,7 @@ target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap $_TARGETNAME configure -work-area-phys 0x20400000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -adapter_khz 1800 +adapter speed 1800 if {![using_hla]} { # if srst is not fitted use SYSRESETREQ to diff --git a/tcl/target/avr32.cfg b/tcl/target/avr32.cfg index f5ee1a486..7808127ca 100644 --- a/tcl/target/avr32.cfg +++ b/tcl/target/avr32.cfg @@ -3,7 +3,7 @@ set _ENDIAN big set _CPUTAPID 0x21e8203f -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 reset_config trst_and_srst separate diff --git a/tcl/target/bcm6348.cfg b/tcl/target/bcm6348.cfg index 2540b51af..a9be55913 100644 --- a/tcl/target/bcm6348.cfg +++ b/tcl/target/bcm6348.cfg @@ -1,7 +1,7 @@ set _CHIPNAME bcm6348 set _CPUID 0x0634817f -adapter_khz 1000 +adapter speed 1000 jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID diff --git a/tcl/target/bluenrg-x.cfg b/tcl/target/bluenrg-x.cfg index b0dd61ae9..109db1708 100644 --- a/tcl/target/bluenrg-x.cfg +++ b/tcl/target/bluenrg-x.cfg @@ -20,7 +20,7 @@ if { [info exists WORKAREASIZE] } { set _WORKAREASIZE 0x5F00 } -adapter_khz 4000 +adapter speed 4000 if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID diff --git a/tcl/target/c100.cfg b/tcl/target/c100.cfg index 1eaa8fe8a..5b4354e90 100644 --- a/tcl/target/c100.cfg +++ b/tcl/target/c100.cfg @@ -3,7 +3,7 @@ # this script only configures one core (that is used to run Linux) # assume no PLL lock, start slowly -adapter_khz 100 +adapter speed 100 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME diff --git a/tcl/target/c100helper.tcl b/tcl/target/c100helper.tcl index c9124cbc6..9da3730b4 100644 --- a/tcl/target/c100helper.tcl +++ b/tcl/target/c100helper.tcl @@ -491,7 +491,7 @@ proc reboot {} { mww $TIMER_WDT_HIGH_BOUND 0xffffff mww $TIMER_WDT_CURRENT_COUNT 0x0 echo "JTAG speed lowered to 100kHz" - adapter_khz 100 + adapter speed 100 mww $TIMER_WDT_CONTROL 0x1 # wait until the reset echo -n "Wating for watchdog to trigger..." diff --git a/tcl/target/cc2538.cfg b/tcl/target/cc2538.cfg index 63fd9c267..8d232f41f 100755 --- a/tcl/target/cc2538.cfg +++ b/tcl/target/cc2538.cfg @@ -1,7 +1,7 @@ # Config for Texas Instruments low power RF SoC CC2538 # http://www.ti.com/lit/pdf/swru319 -adapter_khz 100 +adapter speed 100 source [find target/icepick.cfg] source [find target/ti-cjtag.cfg] diff --git a/tcl/target/dragonite.cfg b/tcl/target/dragonite.cfg index 750fd6437..1277cca9c 100644 --- a/tcl/target/dragonite.cfg +++ b/tcl/target/dragonite.cfg @@ -26,6 +26,6 @@ set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME dragonite -endian $_ENDIAN -chain-position $_TARGETNAME reset_config trst_and_srst -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 200 diff --git a/tcl/target/dsp56321.cfg b/tcl/target/dsp56321.cfg index 6f3222373..0ac0ce87c 100644 --- a/tcl/target/dsp56321.cfg +++ b/tcl/target/dsp56321.cfg @@ -21,7 +21,7 @@ if { [info exists CPUTAPID] } { } #jtag speed -adapter_khz 4500 +adapter speed 4500 #has only srst reset_config srst_only diff --git a/tcl/target/dsp568013.cfg b/tcl/target/dsp568013.cfg index 0c491fa95..98110c298 100644 --- a/tcl/target/dsp568013.cfg +++ b/tcl/target/dsp568013.cfg @@ -20,7 +20,7 @@ if { [info exists CPUTAPID] } { } #jtag speed -adapter_khz 800 +adapter speed 800 reset_config srst_only diff --git a/tcl/target/dsp568037.cfg b/tcl/target/dsp568037.cfg index 01194d002..010d06f9d 100644 --- a/tcl/target/dsp568037.cfg +++ b/tcl/target/dsp568037.cfg @@ -20,7 +20,7 @@ if { [info exists CPUTAPID] } { } #jtag speed -adapter_khz 800 +adapter speed 800 reset_config srst_only diff --git a/tcl/target/efm32.cfg b/tcl/target/efm32.cfg index e22ce5cba..c789efc72 100644 --- a/tcl/target/efm32.cfg +++ b/tcl/target/efm32.cfg @@ -34,7 +34,7 @@ if { [info exists CPUTAPID] } { swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu -adapter_khz 1000 +adapter speed 1000 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap diff --git a/tcl/target/epc9301.cfg b/tcl/target/epc9301.cfg index f186d37dc..252bbab11 100644 --- a/tcl/target/epc9301.cfg +++ b/tcl/target/epc9301.cfg @@ -20,7 +20,7 @@ if { [info exists CPUTAPID] } { } jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 set _TARGETNAME $_CHIPNAME.cpu diff --git a/tcl/target/esi32xx.cfg b/tcl/target/esi32xx.cfg index d32af39bd..6be84ab07 100644 --- a/tcl/target/esi32xx.cfg +++ b/tcl/target/esi32xx.cfg @@ -26,7 +26,7 @@ if { [info exists CACHEARCH] } { $_TARGETNAME esirisc cache_arch $CACHEARCH } -adapter_khz 2000 +adapter speed 2000 reset_config none diff --git a/tcl/target/feroceon.cfg b/tcl/target/feroceon.cfg index 389576e55..b9344268d 100644 --- a/tcl/target/feroceon.cfg +++ b/tcl/target/feroceon.cfg @@ -26,6 +26,6 @@ set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME feroceon -endian $_ENDIAN -chain-position $_TARGETNAME reset_config trst_and_srst -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 200 diff --git a/tcl/target/fm3.cfg b/tcl/target/fm3.cfg index a0610ce17..376320e83 100644 --- a/tcl/target/fm3.cfg +++ b/tcl/target/fm3.cfg @@ -22,7 +22,7 @@ if { [info exists CPUTAPID] } { } # delays on reset lines -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } @@ -45,7 +45,7 @@ set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME # 4MHz / 6 = 666kHz, so use 500 -adapter_khz 500 +adapter speed 500 if {![using_hla]} { # if srst is not fitted use SYSRESETREQ to diff --git a/tcl/target/fm4.cfg b/tcl/target/fm4.cfg index b79634d96..bfe7115ca 100644 --- a/tcl/target/fm4.cfg +++ b/tcl/target/fm4.cfg @@ -24,7 +24,7 @@ dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap -adapter_khz 500 +adapter speed 500 if {![using_hla]} { cortex_m reset_config sysresetreq diff --git a/tcl/target/gp326xxxa.cfg b/tcl/target/gp326xxxa.cfg index feb7554b7..df42c4485 100644 --- a/tcl/target/gp326xxxa.cfg +++ b/tcl/target/gp326xxxa.cfg @@ -33,11 +33,11 @@ $_TARGETNAME configure -work-area-phys 0xf8000000 -work-area-size 0x8000 -work-a reset_config trst_and_srst srst_pulls_trst # This delay is needed otherwise communication with the target would # be unreliable -adapter_nsrst_delay 100 +adapter srst delay 100 # Set the adapter speed ridiculously low just in case we are # running off of a 32kHz clock -adapter_khz 2 +adapter speed 2 proc gp32xxxa_halt_and_reset_control_registers {} { # System control registers @@ -57,7 +57,7 @@ proc gp32xxxa_halt_and_reset_control_registers {} { # Set the adapter speed ridiculously low just in case we are # running off of a 32kHz clock - adapter_khz 2 + adapter speed 2 # Disable any advanced features at this stage arm7_9 dcc_downloads disable @@ -86,7 +86,7 @@ proc gp32xxxa_halt_and_reset_control_registers {} { # Now that we know that we are running at 48Mhz # Increase JTAG speed and enable speed optimization features - adapter_khz 5000 + adapter speed 5000 arm7_9 dcc_downloads enable arm7_9 fast_memory_access enable } diff --git a/tcl/target/imx28.cfg b/tcl/target/imx28.cfg index 4cc3950be..1fea3fa37 100644 --- a/tcl/target/imx28.cfg +++ b/tcl/target/imx28.cfg @@ -4,7 +4,7 @@ reset_config trst_and_srst #jtag nTRST and nSRST delay -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 if { [info exists CHIPNAME] } { diff --git a/tcl/target/imx31.cfg b/tcl/target/imx31.cfg index ca639515f..d850657da 100644 --- a/tcl/target/imx31.cfg +++ b/tcl/target/imx31.cfg @@ -3,7 +3,7 @@ reset_config trst_and_srst srst_gates_jtag -adapter_nsrst_delay 5 +adapter srst delay 5 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME diff --git a/tcl/target/imx6.cfg b/tcl/target/imx6.cfg index f359346d7..29453346a 100644 --- a/tcl/target/imx6.cfg +++ b/tcl/target/imx6.cfg @@ -75,7 +75,7 @@ proc imx6_dbginit {target} { } # Slow speed to be sure it will work -adapter_khz 1000 -$_TARGETNAME configure -event reset-start { adapter_khz 1000 } +adapter speed 1000 +$_TARGETNAME configure -event reset-start { adapter speed 1000 } $_TARGETNAME configure -event reset-assert-post "imx6_dbginit $_TARGETNAME" diff --git a/tcl/target/is5114.cfg b/tcl/target/is5114.cfg index 31f1aa1aa..1a06b091f 100644 --- a/tcl/target/is5114.cfg +++ b/tcl/target/is5114.cfg @@ -23,7 +23,7 @@ if { [info exists CPUTAPID] } { } # jtag speed. We need to stick to 16kHz until we've finished reset. -adapter_khz 16 +adapter speed 16 reset_config trst_and_srst @@ -38,9 +38,9 @@ jtag newtap $_CHIPNAME unknown2 -irlen 5 -ircapture 1 -irmask 1 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME -$_TARGETNAME configure -event reset-start { adapter_khz 16 } +$_TARGETNAME configure -event reset-start { adapter speed 16 } $_TARGETNAME configure -event reset-init { # We can increase speed now that we know the target is halted. - adapter_khz 3000 + adapter speed 3000 } $_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1 diff --git a/tcl/target/k1921vk01t.cfg b/tcl/target/k1921vk01t.cfg index 1a8402106..926f3c726 100755 --- a/tcl/target/k1921vk01t.cfg +++ b/tcl/target/k1921vk01t.cfg @@ -40,9 +40,9 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE flash bank $_CHIPNAME.flash niietcm4 0 0 0 0 $_TARGETNAME -adapter_khz 2000 +adapter speed 2000 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } diff --git a/tcl/target/ke0x.cfg b/tcl/target/ke0x.cfg index 8239400d0..b92721f4c 100644 --- a/tcl/target/ke0x.cfg +++ b/tcl/target/ke0x.cfg @@ -35,7 +35,7 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME -adapter_khz 1000 +adapter speed 1000 reset_config srst_nogate diff --git a/tcl/target/klx.cfg b/tcl/target/klx.cfg index 5d9286a69..36b6ed596 100644 --- a/tcl/target/klx.cfg +++ b/tcl/target/klx.cfg @@ -40,7 +40,7 @@ kinetis create_banks # Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual # specifies up to 1MHz for VLPR mode and up to 24MHz for run mode; # Table 17 of Sub-Family Data Sheet rev4 lists 25MHz as the maximum frequency. -adapter_khz 1000 +adapter speed 1000 reset_config srst_nogate diff --git a/tcl/target/ks869x.cfg b/tcl/target/ks869x.cfg index 0f6829c91..78cc402b4 100644 --- a/tcl/target/ks869x.cfg +++ b/tcl/target/ks869x.cfg @@ -18,7 +18,7 @@ if { [info exists CPUTAPID] } { set _CPUTAPID 0x00922f0f } -adapter_khz 6000 +adapter speed 6000 # jtag scan chain jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID diff --git a/tcl/target/kx.cfg b/tcl/target/kx.cfg index 73ee62a79..0ff5b0c53 100644 --- a/tcl/target/kx.cfg +++ b/tcl/target/kx.cfg @@ -41,7 +41,7 @@ set _FLASHNAME $_CHIPNAME.pflash flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME kinetis create_banks -adapter_khz 1000 +adapter speed 1000 reset_config srst_nogate diff --git a/tcl/target/lpc1850.cfg b/tcl/target/lpc1850.cfg index 925a0498d..481dc8aaf 100644 --- a/tcl/target/lpc1850.cfg +++ b/tcl/target/lpc1850.cfg @@ -1,6 +1,6 @@ source [find target/swj-dp.tcl] -adapter_khz 500 +adapter speed 500 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME diff --git a/tcl/target/lpc1xxx.cfg b/tcl/target/lpc1xxx.cfg index 1969e464f..946d1ce16 100644 --- a/tcl/target/lpc1xxx.cfg +++ b/tcl/target/lpc1xxx.cfg @@ -145,10 +145,10 @@ if { $_CHIPSERIES == "lpc800" || $_CHIPSERIES == "lpc1100" || $_CHIPSERIES == "l # Run with *real slow* clock by default since the # boot rom could have been playing with the PLL, so # we have no idea what clock the target is running at. -adapter_khz 10 +adapter speed 10 # delays on reset lines -adapter_nsrst_delay 200 +adapter srst delay 200 if {[using_jtag]} { jtag_ntrst_delay 200 } diff --git a/tcl/target/lpc2xxx.cfg b/tcl/target/lpc2xxx.cfg index 11f1c48bc..4c3394c95 100644 --- a/tcl/target/lpc2xxx.cfg +++ b/tcl/target/lpc2xxx.cfg @@ -13,10 +13,10 @@ proc setup_lpc2xxx {chip_name cputapids flash_size flash_variant workarea_size c reset_config trst_and_srst # reset delays - adapter_nsrst_delay 100 + adapter srst delay 100 jtag_ntrst_delay 100 - adapter_khz $adapter_freq_khz + adapter speed $adapter_freq_khz foreach i $cputapids { append expected_ids "-expected-id " $i " " diff --git a/tcl/target/lpc3131.cfg b/tcl/target/lpc3131.cfg index 27c1f6757..185c0aad8 100644 --- a/tcl/target/lpc3131.cfg +++ b/tcl/target/lpc3131.cfg @@ -52,7 +52,7 @@ dict set lpc313x wdt 0x13002400 # Target configuration ################################################################## -adapter_nsrst_delay 1000 +adapter srst delay 1000 jtag_ntrst_delay 0 set _TARGETNAME $_CHIPNAME.cpu diff --git a/tcl/target/lpc4350.cfg b/tcl/target/lpc4350.cfg index 2b728840e..0c6d0ffdf 100644 --- a/tcl/target/lpc4350.cfg +++ b/tcl/target/lpc4350.cfg @@ -1,6 +1,6 @@ source [find target/swj-dp.tcl] -adapter_khz 500 +adapter speed 500 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME diff --git a/tcl/target/lpc4370.cfg b/tcl/target/lpc4370.cfg index 1374ef275..9db2b9e92 100644 --- a/tcl/target/lpc4370.cfg +++ b/tcl/target/lpc4370.cfg @@ -2,7 +2,7 @@ # NXP LPC4370 - 1x ARM Cortex-M4 + 2x ARM Cortex-M0 @ up to 204 MHz each # -adapter_khz 500 +adapter speed 500 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME diff --git a/tcl/target/lpc8nxx.cfg b/tcl/target/lpc8nxx.cfg index b9332909a..1bc77b20d 100644 --- a/tcl/target/lpc8nxx.cfg +++ b/tcl/target/lpc8nxx.cfg @@ -22,7 +22,7 @@ if {![using_hla]} { # If srst is not fitted use SYSRESETREQ to perform a soft reset cortex_m reset_config sysresetreq } -adapter_nsrst_delay 100 +adapter srst delay 100 $_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size 0x1ff0 -work-area-backup 0 diff --git a/tcl/target/ls1012a.cfg b/tcl/target/ls1012a.cfg index 9a9e684d7..19d3e5838 100644 --- a/tcl/target/ls1012a.cfg +++ b/tcl/target/ls1012a.cfg @@ -32,4 +32,4 @@ target create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -dbgbase 0x80410000 -cti target smp $_TARGETNAME -adapter_khz 2000 +adapter speed 2000 diff --git a/tcl/target/max32620.cfg b/tcl/target/max32620.cfg index 80cb25a47..6187bb996 100644 --- a/tcl/target/max32620.cfg +++ b/tcl/target/max32620.cfg @@ -2,7 +2,7 @@ # www.maximintegrated.com # adapter speed -adapter_khz 4000 +adapter speed 4000 # reset pin configuration reset_config srst_only diff --git a/tcl/target/max32625.cfg b/tcl/target/max32625.cfg index 7182b235f..159b36094 100644 --- a/tcl/target/max32625.cfg +++ b/tcl/target/max32625.cfg @@ -2,7 +2,7 @@ # www.maximintegrated.com # adapter speed -adapter_khz 4000 +adapter speed 4000 # reset pin configuration reset_config srst_only diff --git a/tcl/target/max3263x.cfg b/tcl/target/max3263x.cfg index f23b0b64d..fc7d11f5c 100644 --- a/tcl/target/max3263x.cfg +++ b/tcl/target/max3263x.cfg @@ -2,7 +2,7 @@ # www.maximintegrated.com # adapter speed -adapter_khz 4000 +adapter speed 4000 # reset pin configuration reset_config srst_only diff --git a/tcl/target/mc13224v.cfg b/tcl/target/mc13224v.cfg index 27ac8c3b2..f756dd963 100644 --- a/tcl/target/mc13224v.cfg +++ b/tcl/target/mc13224v.cfg @@ -35,8 +35,8 @@ reset_config srst_only jtag_ntrst_delay 200 # rclk hasn't been working well. This maybe the mc13224v or something else. -#adapter_khz 2000 -adapter_khz 2000 +#adapter speed 2000 +adapter speed 2000 ###################### # Target configuration diff --git a/tcl/target/mdr32f9q2i.cfg b/tcl/target/mdr32f9q2i.cfg index 67481024c..820d2dd45 100644 --- a/tcl/target/mdr32f9q2i.cfg +++ b/tcl/target/mdr32f9q2i.cfg @@ -49,9 +49,9 @@ if { [info exists IMEMORY] && [string equal $IMEMORY true] } { } # JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -adapter_khz 1000 +adapter speed 1000 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } diff --git a/tcl/target/nrf51.cfg b/tcl/target/nrf51.cfg index 4f2402033..d51a50e23 100644 --- a/tcl/target/nrf51.cfg +++ b/tcl/target/nrf51.cfg @@ -50,7 +50,7 @@ flash bank $_CHIPNAME.uicr nrf51 0x10001000 0 1 1 $_TARGETNAME # The chip should start up from internal 16Mhz RC, so setting adapter # clock to 1Mhz should be OK # -adapter_khz 1000 +adapter speed 1000 proc enable_all_ram {} { # nRF51822 Product Anomaly Notice (PAN) #16 explains that not all RAM banks diff --git a/tcl/target/nrf52.cfg b/tcl/target/nrf52.cfg index c29adbdd6..00901bf8a 100644 --- a/tcl/target/nrf52.cfg +++ b/tcl/target/nrf52.cfg @@ -30,7 +30,7 @@ dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap -adapter_khz 1000 +adapter speed 1000 $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 diff --git a/tcl/target/numicro.cfg b/tcl/target/numicro.cfg index c42dfbc2f..73022df47 100644 --- a/tcl/target/numicro.cfg +++ b/tcl/target/numicro.cfg @@ -48,7 +48,7 @@ set _FLASHNAME $_CHIPNAME.flash_config flash bank $_FLASHNAME numicro 0x00300000 0 0 0 $_TARGETNAME # set default SWCLK frequency -adapter_khz 1000 +adapter speed 1000 # set default srst setting "none" reset_config none diff --git a/tcl/target/omap3530.cfg b/tcl/target/omap3530.cfg index 078d7f24d..dcf7c5139 100644 --- a/tcl/target/omap3530.cfg +++ b/tcl/target/omap3530.cfg @@ -63,8 +63,8 @@ proc omap3_dbginit {target} { # be absolutely certain the JTAG clock will work with the worst-case # 16.8MHz/2 = 8.4MHz core clock, even before a bootloader kicks in. # OK to speed up *after* PLL and clock tree setup. -adapter_khz 1000 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1000 } +adapter speed 1000 +$_TARGETNAME configure -event "reset-start" { adapter speed 1000 } # Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset # ourselves using PRM_RSTCTRL. RST_GS (2) is a warm reset, like ICEpick diff --git a/tcl/target/omap5912.cfg b/tcl/target/omap5912.cfg index c4ff40e23..2f9338bc3 100644 --- a/tcl/target/omap5912.cfg +++ b/tcl/target/omap5912.cfg @@ -14,7 +14,7 @@ if { [info exists CPUTAPID] } { set _CPUTAPID 0x0692602f } -adapter_nsrst_delay 100 +adapter srst delay 100 # NOTE: presumes irlen 38 is the C55x DSP, matching BSDL for # its standalone siblings (like TMS320VC5502) of the same era diff --git a/tcl/target/omapl138.cfg b/tcl/target/omapl138.cfg index fd9ff4c2e..30cf23c9e 100644 --- a/tcl/target/omapl138.cfg +++ b/tcl/target/omapl138.cfg @@ -52,8 +52,8 @@ $_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000 # be absolutely certain the JTAG clock will work with the worst-case # CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns # on the PLL and starts using it. OK to speed up after clock setup. -adapter_khz 1500 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1500 } +adapter speed 1500 +$_TARGETNAME configure -event "reset-start" { adapter speed 1500 } arm7_9 fast_memory_access enable arm7_9 dcc_downloads enable diff --git a/tcl/target/pic32mx.cfg b/tcl/target/pic32mx.cfg index d53b99a58..51a6bbddb 100644 --- a/tcl/target/pic32mx.cfg +++ b/tcl/target/pic32mx.cfg @@ -23,7 +23,7 @@ if { [info exists WORKAREASIZE] } { set _WORKAREASIZE 0x4000 } -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 #jtag scan chain diff --git a/tcl/target/psoc4.cfg b/tcl/target/psoc4.cfg index 544e10987..b56828207 100644 --- a/tcl/target/psoc4.cfg +++ b/tcl/target/psoc4.cfg @@ -36,7 +36,7 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME -adapter_khz 1500 +adapter speed 1500 # Reset, bloody PSoC 4 reset # @@ -118,7 +118,7 @@ proc ocd_process_reset_inner { MODE } { } if { ! [info exists PSOC4_USE_ACQUIRE] } { - if { 0 == [string compare [adapter_name] kitprog ] } { + if { 0 == [string compare [adapter name] kitprog ] } { set PSOC4_USE_ACQUIRE 1 } else { set PSOC4_USE_ACQUIRE 0 @@ -138,7 +138,7 @@ proc ocd_process_reset_inner { MODE } { $t invoke-event reset-assert-pre if { $halt && $PSOC4_USE_ACQUIRE } { - catch { [adapter_name] acquire_psoc } + catch { [adapter name] acquire_psoc } $t arp_examine } else { if { $PSOC4_TEST_MODE_WORKAROUND } { diff --git a/tcl/target/psoc6.cfg b/tcl/target/psoc6.cfg index fc0c71159..51d032b17 100644 --- a/tcl/target/psoc6.cfg +++ b/tcl/target/psoc6.cfg @@ -6,7 +6,7 @@ source [find target/swj-dp.tcl] -adapter_khz 1000 +adapter speed 1000 global _CHIPNAME if { [info exists CHIPNAME] } { diff --git a/tcl/target/pxa255.cfg b/tcl/target/pxa255.cfg index 4b222de08..73518bf7e 100644 --- a/tcl/target/pxa255.cfg +++ b/tcl/target/pxa255.cfg @@ -28,8 +28,8 @@ target create $_TARGETNAME xscale -endian $_ENDIAN \ # PXA255 comes out of reset using 3.6864 MHz oscillator. # Until the PLL kicks in, keep the JTAG clock slow enough # that we get no errors. -adapter_khz 300 -$_TARGETNAME configure -event "reset-start" { adapter_khz 300 } +adapter speed 300 +$_TARGETNAME configure -event "reset-start" { adapter speed 300 } # both TRST and SRST are *required* for debug # DCSR is often accessed with SRST active diff --git a/tcl/target/pxa270.cfg b/tcl/target/pxa270.cfg index 95f7f16f0..bd904b5dd 100644 --- a/tcl/target/pxa270.cfg +++ b/tcl/target/pxa270.cfg @@ -34,9 +34,9 @@ if { [info exists CPUTAPID3] } { set _CPUTAPID3 0x89265013 } -# set adapter_nsrst_delay to the delay introduced by your reset circuit +# set adapter srst delay to the delay introduced by your reset circuit # the rest of the needed delays are built into the openocd program -adapter_nsrst_delay 260 +adapter srst delay 260 # set the jtag_ntrst_delay to the delay introduced by a reset circuit # the rest of the needed delays are built into the openocd program jtag_ntrst_delay 250 diff --git a/tcl/target/pxa3xx.cfg b/tcl/target/pxa3xx.cfg index c459f6eaa..1a4539ca9 100644 --- a/tcl/target/pxa3xx.cfg +++ b/tcl/target/pxa3xx.cfg @@ -59,9 +59,9 @@ if { [info exists CPUTAPID_PXA32X_C0] } { set _CPUTAPID_PXA32X_C0 0x7E642013 } -# set adapter_nsrst_delay to the delay introduced by your reset circuit +# set adapter srst delay to the delay introduced by your reset circuit # the rest of the needed delays are built into the openocd program -adapter_nsrst_delay 260 +adapter srst delay 260 # set the jtag_ntrst_delay to the delay introduced by a reset circuit # the rest of the needed delays are built into the openocd program diff --git a/tcl/target/qualcomm_qca4531.cfg b/tcl/target/qualcomm_qca4531.cfg index 3d2157852..0b046b842 100644 --- a/tcl/target/qualcomm_qca4531.cfg +++ b/tcl/target/qualcomm_qca4531.cfg @@ -38,12 +38,12 @@ reset_config none srst_pulls_trst # For SRST based variant we still need proper timings. # For ETH part the reset should be asserted at least for 10ms # Since there is no other information let's take 100ms to be sure. -adapter_nsrst_assert_width 100 +adapter srst pulse_width 100 # according to the SoC documentation it should take at least 5ms from # reset end till bootstrap end. In the practice we need 8ms to get JTAG back # to live. -adapter_nsrst_delay 8 +adapter srst delay 8 if { [info exists CHIPNAME] } { set _CHIPNAME $_CHIPNAME diff --git a/tcl/target/readme.txt b/tcl/target/readme.txt index f028b11c7..2c3cc8df1 100644 --- a/tcl/target/readme.txt +++ b/tcl/target/readme.txt @@ -26,12 +26,12 @@ assumed that all write-protect mechanisms should be disabled. flash write_image [file] verify_image [file] -4. adapter_khz sets the maximum speed (or alternatively RCLK). If invoked +4. adapter speed sets the maximum speed (or alternatively RCLK). If invoked multiple times only the last setting is used. interface/xxx.cfg files are always executed *before* target/xxx.cfg -files, so any adapter_khz in interface/xxx.cfg will be overridden by -target/xxx.cfg. adapter_khz in interface/xxx.cfg would then, effectively, +files, so any adapter speed in interface/xxx.cfg will be overridden by +target/xxx.cfg. adapter speed in interface/xxx.cfg would then, effectively, set the default JTAG speed. Note that a target/xxx.cfg file can invoke another target/yyy.cfg file, diff --git a/tcl/target/renesas_s7g2.cfg b/tcl/target/renesas_s7g2.cfg index 78fb3e82f..b4be88f61 100644 --- a/tcl/target/renesas_s7g2.cfg +++ b/tcl/target/renesas_s7g2.cfg @@ -48,4 +48,4 @@ if { ![using_hla] } { cortex_m reset_config sysresetreq } -adapter_khz 1000 +adapter speed 1000 diff --git a/tcl/target/samsung_s3c2450.cfg b/tcl/target/samsung_s3c2450.cfg index 1bc4f2d87..248255719 100644 --- a/tcl/target/samsung_s3c2450.cfg +++ b/tcl/target/samsung_s3c2450.cfg @@ -7,11 +7,11 @@ # # RCLK? # -# adapter_khz 0 +# adapter speed 0 # # Really low clock during reset? # -# adapter_khz 1 +# adapter speed 1 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME diff --git a/tcl/target/samsung_s3c6410.cfg b/tcl/target/samsung_s3c6410.cfg index 88fe966dc..9f7c2cddf 100644 --- a/tcl/target/samsung_s3c6410.cfg +++ b/tcl/target/samsung_s3c6410.cfg @@ -40,7 +40,7 @@ jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_C set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME -adapter_nsrst_delay 500 +adapter srst delay 500 jtag_ntrst_delay 500 #reset configuration diff --git a/tcl/target/sim3x.cfg b/tcl/target/sim3x.cfg index ed46a3b34..3d3fc5c3e 100755 --- a/tcl/target/sim3x.cfg +++ b/tcl/target/sim3x.cfg @@ -48,9 +48,9 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME -adapter_khz 1000 +adapter speed 1000 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } diff --git a/tcl/target/smp8634.cfg b/tcl/target/smp8634.cfg index c13414c87..e95f633db 100644 --- a/tcl/target/smp8634.cfg +++ b/tcl/target/smp8634.cfg @@ -18,7 +18,7 @@ if { [info exists CPUTAPID] } { set _CPUTAPID 0x08630001 } -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 reset_config trst_and_srst separate diff --git a/tcl/target/stellaris.cfg b/tcl/target/stellaris.cfg index 7fffd2a7c..fb591c2bf 100644 --- a/tcl/target/stellaris.cfg +++ b/tcl/target/stellaris.cfg @@ -68,7 +68,7 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE # NOTE: this may be increased by a reset-init handler, after it # configures and enables the PLL. Or you might need to decrease # this, if you're using a slower clock. -adapter_khz 500 +adapter speed 500 source [find mem_helper.tcl] @@ -132,7 +132,7 @@ proc reset_peripherals {family} { } $_TARGETNAME configure -event reset-start { - adapter_khz 500 + adapter speed 500 # # When nRST is asserted on most Stellaris devices, it clears some of diff --git a/tcl/target/stm32f0x.cfg b/tcl/target/stm32f0x.cfg index baac9b68d..b20d036cf 100644 --- a/tcl/target/stm32f0x.cfg +++ b/tcl/target/stm32f0x.cfg @@ -52,9 +52,9 @@ set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME # adapter speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -adapter_khz 1000 +adapter speed 1000 -adapter_nsrst_delay 100 +adapter srst delay 100 reset_config srst_nogate @@ -66,7 +66,7 @@ if {![using_hla]} { proc stm32f0x_default_reset_start {} { # Reset clock is HSI (8 MHz) - adapter_khz 1000 + adapter speed 1000 } proc stm32f0x_default_examine_end {} { @@ -86,7 +86,7 @@ proc stm32f0x_default_reset_init {} { mmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1] # Boost JTAG frequency - adapter_khz 8000 + adapter speed 8000 } # Default hooks diff --git a/tcl/target/stm32f1x.cfg b/tcl/target/stm32f1x.cfg index 471878d7f..3e85fb217 100644 --- a/tcl/target/stm32f1x.cfg +++ b/tcl/target/stm32f1x.cfg @@ -60,9 +60,9 @@ set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME # JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz -adapter_khz 1000 +adapter speed 1000 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } diff --git a/tcl/target/stm32f2x.cfg b/tcl/target/stm32f2x.cfg index 1e8b94ace..d790febd5 100644 --- a/tcl/target/stm32f2x.cfg +++ b/tcl/target/stm32f2x.cfg @@ -28,9 +28,9 @@ if { [info exists WORKAREASIZE] } { # bit more to be on the safe side. Perhaps superstition, but if are # running off a crystal, we can run closer to the limit. Note # that there can be a pretty wide band where things are more or less stable. -adapter_khz 1000 +adapter speed 1000 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } diff --git a/tcl/target/stm32f3x.cfg b/tcl/target/stm32f3x.cfg index 86e9f594e..e3f1a34dd 100644 --- a/tcl/target/stm32f3x.cfg +++ b/tcl/target/stm32f3x.cfg @@ -28,9 +28,9 @@ if { [info exists WORKAREASIZE] } { # bit more to be on the safe side. Perhaps superstition, but if are # running off a crystal, we can run closer to the limit. Note # that there can be a pretty wide band where things are more or less stable. -adapter_khz 1000 +adapter speed 1000 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } @@ -73,7 +73,7 @@ if {![using_hla]} { proc stm32f3x_default_reset_start {} { # Reset clock is HSI (8 MHz) - adapter_khz 1000 + adapter speed 1000 } proc stm32f3x_default_examine_end {} { @@ -93,7 +93,7 @@ proc stm32f3x_default_reset_init {} { mmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1] # Boost JTAG frequency - adapter_khz 8000 + adapter speed 8000 } # Default hooks diff --git a/tcl/target/stm32f4x.cfg b/tcl/target/stm32f4x.cfg index 09ce14a5d..b95e783c5 100644 --- a/tcl/target/stm32f4x.cfg +++ b/tcl/target/stm32f4x.cfg @@ -58,9 +58,9 @@ flash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME # bit more to be on the safe side. Perhaps superstition, but if are # running off a crystal, we can run closer to the limit. Note # that there can be a pretty wide band where things are more or less stable. -adapter_khz 2000 +adapter speed 2000 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } @@ -100,10 +100,10 @@ $_TARGETNAME configure -event reset-init { mmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL # Boost JTAG frequency - adapter_khz 8000 + adapter speed 8000 } $_TARGETNAME configure -event reset-start { # Reduce speed since CPU speed will slow down to 16MHz with the reset - adapter_khz 2000 + adapter speed 2000 } diff --git a/tcl/target/stm32f7x.cfg b/tcl/target/stm32f7x.cfg index ba1d12ffb..db1794c19 100755 --- a/tcl/target/stm32f7x.cfg +++ b/tcl/target/stm32f7x.cfg @@ -65,9 +65,9 @@ flash bank $_CHIPNAME.otp stm32f2x 0x1ff0f000 0 0 0 $_TARGETNAME flash bank $_CHIPNAME.itcm-flash.alias virtual 0x00200000 0 0 0 $_TARGETNAME $_FLASHNAME # adapter speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz -adapter_khz 2000 +adapter speed 2000 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } @@ -162,12 +162,12 @@ $_TARGETNAME configure -event reset-init { if {[using_jtag]} { [[target current] cget -dap] memaccess 16 } { - adapter_khz 8000 + adapter speed 8000 } } $_TARGETNAME configure -event reset-start { # Reduce speed since CPU speed will slow down to 16MHz with the reset - adapter_khz 2000 + adapter speed 2000 } diff --git a/tcl/target/stm32h7x.cfg b/tcl/target/stm32h7x.cfg index 1d116542a..2d92eca92 100644 --- a/tcl/target/stm32h7x.cfg +++ b/tcl/target/stm32h7x.cfg @@ -105,9 +105,9 @@ if {[set $_CHIPNAME.DUAL_CORE]} { targets $_CHIPNAME.cpu0 # Clock after reset is HSI at 64 MHz, no need of PLL -adapter_khz 1800 +adapter speed 1800 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } @@ -170,7 +170,7 @@ $_CHIPNAME.cpu0 configure -event trace-config { $_CHIPNAME.cpu0 configure -event reset-init { # Clock after reset is HSI at 64 MHz, no need of PLL - adapter_khz 4000 + adapter speed 4000 } if {[set $_CHIPNAME.DUAL_CORE]} { diff --git a/tcl/target/stm32l0.cfg b/tcl/target/stm32l0.cfg index e09af8001..7653d13ef 100644 --- a/tcl/target/stm32l0.cfg +++ b/tcl/target/stm32l0.cfg @@ -24,9 +24,9 @@ if { [info exists WORKAREASIZE] } { # JTAG speed should be <= F_CPU/6. # F_CPU after reset is ~2MHz, so use F_JTAG max = 333kHz -adapter_khz 300 +adapter speed 300 -adapter_nsrst_delay 100 +adapter srst delay 100 if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID @@ -70,7 +70,7 @@ proc stm32l0_enable_HSI16 {} { while { ([ mrw 0x4002100c ] & 0x0c) != 0x04 } { } # Increase speed - adapter_khz 2500 + adapter speed 2500 } $_TARGETNAME configure -event reset-init { @@ -78,7 +78,7 @@ $_TARGETNAME configure -event reset-init { } $_TARGETNAME configure -event reset-start { - adapter_khz 300 + adapter speed 300 } $_TARGETNAME configure -event examine-end { diff --git a/tcl/target/stm32l1.cfg b/tcl/target/stm32l1.cfg index 0933151a0..a81d7c798 100644 --- a/tcl/target/stm32l1.cfg +++ b/tcl/target/stm32l1.cfg @@ -23,9 +23,9 @@ if { [info exists WORKAREASIZE] } { # JTAG speed should be <= F_CPU/6. # F_CPU after reset is 2MHz, so use F_JTAG max = 333kHz -adapter_khz 300 +adapter speed 300 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } @@ -79,7 +79,7 @@ proc stm32l_enable_HSI {} { mmw 0x40023808 0x00000001 0 # Increase JTAG speed - adapter_khz 2000 + adapter speed 2000 } $_TARGETNAME configure -event reset-init { @@ -87,7 +87,7 @@ $_TARGETNAME configure -event reset-init { } $_TARGETNAME configure -event reset-start { - adapter_khz 300 + adapter speed 300 } $_TARGETNAME configure -event examine-end { diff --git a/tcl/target/stm32l4x.cfg b/tcl/target/stm32l4x.cfg index 496b47a72..46e6f7e0d 100644 --- a/tcl/target/stm32l4x.cfg +++ b/tcl/target/stm32l4x.cfg @@ -56,9 +56,9 @@ flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME # # Note that there is a pretty wide band where things are # more or less stable, see http://openocd.zylin.com/#/c/3366/ -adapter_khz 500 +adapter speed 500 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } @@ -78,12 +78,12 @@ $_TARGETNAME configure -event reset-init { mww 0x40022000 0x00000103 ;# FLASH_ACR = PRFTBE | 3(Latency) mww 0x40021000 0x00000099 ;# RCC_CR = MSI_ON | MSIRGSEL | MSI Range 9 # Boost JTAG frequency - adapter_khz 4000 + adapter speed 4000 } $_TARGETNAME configure -event reset-start { # Reset clock is MSI (4 MHz) - adapter_khz 500 + adapter speed 500 } $_TARGETNAME configure -event examine-end { diff --git a/tcl/target/stm8l.cfg b/tcl/target/stm8l.cfg index 5cc99e191..386f371ea 100644 --- a/tcl/target/stm8l.cfg +++ b/tcl/target/stm8l.cfg @@ -79,7 +79,7 @@ $_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocks $_TARGETNAME configure -enable_stm8l # The khz rate does not apply here, only slow <0> and fast <1> -adapter_khz 1 +adapter speed 1 reset_config srst_only diff --git a/tcl/target/stm8s.cfg b/tcl/target/stm8s.cfg index d55e61b08..4768068e8 100644 --- a/tcl/target/stm8s.cfg +++ b/tcl/target/stm8s.cfg @@ -76,7 +76,7 @@ $_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocks #$_TARGETNAME configure -enable_step_irq # The khz rate does not apply here, only slow <0> and fast <1> -adapter_khz 1 +adapter speed 1 reset_config srst_only diff --git a/tcl/target/str710.cfg b/tcl/target/str710.cfg index d26a8b1cf..29faaaa58 100644 --- a/tcl/target/str710.cfg +++ b/tcl/target/str710.cfg @@ -1,5 +1,5 @@ #start slow, speed up after reset -adapter_khz 10 +adapter speed 10 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME @@ -29,9 +29,9 @@ jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_C set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -$_TARGETNAME configure -event reset-start { adapter_khz 10 } +$_TARGETNAME configure -event reset-start { adapter speed 10 } $_TARGETNAME configure -event reset-init { - adapter_khz 6000 + adapter speed 6000 # Because the hardware cannot be interrogated for the protection state # of sectors, initialize all the sectors to be unprotected. The initial diff --git a/tcl/target/str730.cfg b/tcl/target/str730.cfg index 48d3134aa..9a2719472 100644 --- a/tcl/target/str730.cfg +++ b/tcl/target/str730.cfg @@ -1,6 +1,6 @@ #STR730 CPU -adapter_khz 3000 +adapter speed 3000 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME @@ -27,15 +27,15 @@ reset_config trst_and_srst srst_pulls_trst jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID #jtag nTRST and nSRST delay -adapter_nsrst_delay 500 +adapter srst delay 500 jtag_ntrst_delay 500 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm7tdmi -endian little -chain-position 0 -$_TARGETNAME configure -event reset-start { adapter_khz 10 } +$_TARGETNAME configure -event reset-start { adapter speed 10 } $_TARGETNAME configure -event reset-init { - adapter_khz 3000 + adapter speed 3000 # Because the hardware cannot be interrogated for the protection state # of sectors, initialize all the sectors to be unprotected. The initial diff --git a/tcl/target/str750.cfg b/tcl/target/str750.cfg index ef6e7954e..335d5ada9 100644 --- a/tcl/target/str750.cfg +++ b/tcl/target/str750.cfg @@ -19,7 +19,7 @@ if { [info exists CPUTAPID] } { } # jtag speed -adapter_khz 10 +adapter speed 10 #use combined on interfaces or targets that can't set TRST/SRST separately reset_config trst_and_srst srst_pulls_trst @@ -29,15 +29,15 @@ reset_config trst_and_srst srst_pulls_trst jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID #jtag nTRST and nSRST delay -adapter_nsrst_delay 500 +adapter srst delay 500 jtag_ntrst_delay 500 set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm7tdmi -endian little -chain-position 0 -$_TARGETNAME configure -event reset-start { adapter_khz 10 } +$_TARGETNAME configure -event reset-start { adapter speed 10 } $_TARGETNAME configure -event reset-init { - adapter_khz 3000 + adapter speed 3000 init_smi # Because the hardware cannot be interrogated for the protection state diff --git a/tcl/target/str912.cfg b/tcl/target/str912.cfg index 36c0b2a54..7426276bf 100644 --- a/tcl/target/str912.cfg +++ b/tcl/target/str912.cfg @@ -13,9 +13,9 @@ if { [info exists ENDIAN] } { } # jtag speed. We need to stick to 16kHz until we've finished reset. -adapter_khz 16 +adapter speed 16 -adapter_nsrst_delay 100 +adapter srst delay 100 jtag_ntrst_delay 100 #use combined on interfaces or targets that can't set TRST/SRST separately @@ -48,11 +48,11 @@ jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BST set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME -$_TARGETNAME configure -event reset-start { adapter_khz 16 } +$_TARGETNAME configure -event reset-start { adapter speed 16 } $_TARGETNAME configure -event reset-init { # We can increase speed now that we know the target is halted. - #adapter_khz 3000 + #adapter speed 3000 # -- Enable 96K RAM # PFQBC enabled / DTCM & AHB wait-states disabled diff --git a/tcl/target/ti_calypso.cfg b/tcl/target/ti_calypso.cfg index 9d3b293ee..52a84fb9b 100644 --- a/tcl/target/ti_calypso.cfg +++ b/tcl/target/ti_calypso.cfg @@ -32,7 +32,7 @@ if { [info exists WORKAREASIZE] } { set _WORKAREASIZE 0x10000 } -adapter_khz 1000 +adapter speed 1000 reset_config trst_and_srst diff --git a/tcl/target/ti_cc26x0.cfg b/tcl/target/ti_cc26x0.cfg index 7efecb666..8d8a0df4e 100644 --- a/tcl/target/ti_cc26x0.cfg +++ b/tcl/target/ti_cc26x0.cfg @@ -53,4 +53,4 @@ set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME reset_config srst_only -adapter_nsrst_delay 100 +adapter srst delay 100 diff --git a/tcl/target/ti_cc32xx.cfg b/tcl/target/ti_cc32xx.cfg index bc3038d8e..6f91d3fd3 100644 --- a/tcl/target/ti_cc32xx.cfg +++ b/tcl/target/ti_cc32xx.cfg @@ -61,4 +61,4 @@ if { [info exists WORKAREASIZE] } { $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 reset_config srst_only -adapter_nsrst_delay 1100 +adapter srst delay 1100 diff --git a/tcl/target/ti_dm355.cfg b/tcl/target/ti_dm355.cfg index 4f8f523e8..91c008765 100644 --- a/tcl/target/ti_dm355.cfg +++ b/tcl/target/ti_dm355.cfg @@ -98,8 +98,8 @@ $_TARGETNAME configure \ # be absolutely certain the JTAG clock will work with the worst-case # CLKIN = 24 MHz (best case: 36 MHz) even when no bootloader turns # on the PLL and starts using it. OK to speed up after clock setup. -adapter_khz 1500 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1500 } +adapter speed 1500 +$_TARGETNAME configure -event "reset-start" { adapter speed 1500 } arm7_9 fast_memory_access enable arm7_9 dcc_downloads enable diff --git a/tcl/target/ti_dm365.cfg b/tcl/target/ti_dm365.cfg index 0db83dbaa..8b52746bd 100644 --- a/tcl/target/ti_dm365.cfg +++ b/tcl/target/ti_dm365.cfg @@ -90,8 +90,8 @@ $_TARGETNAME configure \ # be absolutely certain the JTAG clock will work with the worst-case # CLKIN = 19.2 MHz (best case: 36 MHz) even when no bootloader turns # on the PLL and starts using it. OK to speed up after clock setup. -adapter_khz 1500 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1500 } +adapter speed 1500 +$_TARGETNAME configure -event "reset-start" { adapter speed 1500 } arm7_9 fast_memory_access enable arm7_9 dcc_downloads enable diff --git a/tcl/target/ti_dm6446.cfg b/tcl/target/ti_dm6446.cfg index fa1e6e957..ccc650a3d 100644 --- a/tcl/target/ti_dm6446.cfg +++ b/tcl/target/ti_dm6446.cfg @@ -70,8 +70,8 @@ $_TARGETNAME configure -work-area-phys 0x0000a000 -work-area-size 0x2000 # be absolutely certain the JTAG clock will work with the worst-case # CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns # on the PLL and starts using it. OK to speed up after clock setup. -adapter_khz 1500 -$_TARGETNAME configure -event "reset-start" { adapter_khz 1500 } +adapter speed 1500 +$_TARGETNAME configure -event "reset-start" { adapter speed 1500 } arm7_9 fast_memory_access enable arm7_9 dcc_downloads enable diff --git a/tcl/target/ti_msp432.cfg b/tcl/target/ti_msp432.cfg index 3407f7505..146e7ee21 100644 --- a/tcl/target/ti_msp432.cfg +++ b/tcl/target/ti_msp432.cfg @@ -48,4 +48,4 @@ set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME reset_config srst_only -adapter_nsrst_delay 100 +adapter srst delay 100 diff --git a/tcl/target/ti_tms570.cfg b/tcl/target/ti_tms570.cfg index ce3a17696..d06ff973f 100644 --- a/tcl/target/ti_tms570.cfg +++ b/tcl/target/ti_tms570.cfg @@ -1,4 +1,4 @@ -adapter_khz 1500 +adapter speed 1500 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME diff --git a/tcl/target/tmpa900.cfg b/tcl/target/tmpa900.cfg index 3ba3591be..8e7070020 100644 --- a/tcl/target/tmpa900.cfg +++ b/tcl/target/tmpa900.cfg @@ -28,7 +28,7 @@ jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CP #use combined on interfaces or targets that can't set TRST/SRST separately reset_config trst_and_srst -adapter_nsrst_delay 20 +adapter srst delay 20 jtag_ntrst_delay 20 ###################### diff --git a/tcl/target/tmpa910.cfg b/tcl/target/tmpa910.cfg index 5d41c8c2a..d933c0b2a 100644 --- a/tcl/target/tmpa910.cfg +++ b/tcl/target/tmpa910.cfg @@ -28,7 +28,7 @@ jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CP #use combined on interfaces or targets that can't set TRST/SRST separately reset_config trst_and_srst -adapter_nsrst_delay 20 +adapter srst delay 20 jtag_ntrst_delay 20 ###################### diff --git a/tcl/target/u8500.cfg b/tcl/target/u8500.cfg index 7ff39291b..faaf97d17 100644 --- a/tcl/target/u8500.cfg +++ b/tcl/target/u8500.cfg @@ -314,7 +314,7 @@ global _MAXSPEED set _MAXSPEED $MAXSPEED } global _MAXSPEED -adapter_khz $_MAXSPEED +adapter speed $_MAXSPEED gdb_breakpoint_override hard diff --git a/tcl/target/vybrid_vf6xx.cfg b/tcl/target/vybrid_vf6xx.cfg index 7cb916d1f..c888d259f 100644 --- a/tcl/target/vybrid_vf6xx.cfg +++ b/tcl/target/vybrid_vf6xx.cfg @@ -34,4 +34,4 @@ dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu set _TARGETNAME $_CHIPNAME.cpu target create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap -dbgbase 0xc0088000 target create ${_TARGETNAME}1 cortex_m -dap $_CHIPNAME.dap -ap-num 3 -defer-examine -adapter_khz 1000 +adapter speed 1000 diff --git a/tcl/target/xmc1xxx.cfg b/tcl/target/xmc1xxx.cfg index e693b59db..eb94d7b3c 100644 --- a/tcl/target/xmc1xxx.cfg +++ b/tcl/target/xmc1xxx.cfg @@ -38,4 +38,4 @@ $_TARGETNAME configure -work-area-phys 0x20000000 \ set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME xmc1xxx 0x10000000 0 0 0 $_TARGETNAME -adapter_khz 1000 +adapter speed 1000 diff --git a/tcl/target/xmc4xxx.cfg b/tcl/target/xmc4xxx.cfg index e106d34e3..3020b28b0 100644 --- a/tcl/target/xmc4xxx.cfg +++ b/tcl/target/xmc4xxx.cfg @@ -57,4 +57,4 @@ if { ![using_hla] } { cortex_m reset_config sysresetreq } -adapter_khz 1000 +adapter speed 1000 diff --git a/tcl/target/zynq_7000.cfg b/tcl/target/zynq_7000.cfg index 1562768c5..b4b6f9f18 100644 --- a/tcl/target/zynq_7000.cfg +++ b/tcl/target/zynq_7000.cfg @@ -23,7 +23,7 @@ target create ${_TARGETNAME}1 cortex_a -dap $_CHIPNAME.dap \ -coreid 1 -dbgbase 0x80092000 target smp ${_TARGETNAME}0 ${_TARGETNAME}1 -adapter_khz 1000 +adapter speed 1000 ${_TARGETNAME}0 configure -event reset-assert-post "cortex_a dbginit" ${_TARGETNAME}1 configure -event reset-assert-post "cortex_a dbginit" diff --git a/tcl/target/к1879xб1я.cfg b/tcl/target/к1879xб1я.cfg index 7d8c11358..0a8467f49 100644 --- a/tcl/target/к1879xб1я.cfg +++ b/tcl/target/к1879xб1я.cfg @@ -1,7 +1,7 @@ # СБИС К1879ХБ1Я # http://www.module.ru/catalog/micro/mikroshema_dekodera_cifrovogo_televizionnogo_signala_sbis_k1879hb1ya/ -adapter_khz 1000 +adapter speed 1000 if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME diff --git a/tcl/test/syntax1.cfg b/tcl/test/syntax1.cfg index 5d013f073..04e615ec0 100644 --- a/tcl/test/syntax1.cfg +++ b/tcl/test/syntax1.cfg @@ -1,4 +1,4 @@ -adapter_nsrst_delay 200 +adapter srst delay 200 jtag_ntrst_delay 200 #use combined on interfaces or targets that can't set TRST/SRST separately diff --git a/tcl/tools/firmware-recovery.tcl b/tcl/tools/firmware-recovery.tcl index 8e017ce5b..8b28656aa 100644 --- a/tcl/tools/firmware-recovery.tcl +++ b/tcl/tools/firmware-recovery.tcl @@ -29,7 +29,7 @@ dump_part save partition's contents to a file erase_part erase the given partition flash_part erase, flash and verify the given partition ram_boot load binary file to RAM and run it -adapter_khz set JTAG clock frequency in kHz +adapter speed set JTAG clock frequency in kHz For example, to clear nvram and reflash CFE on an RT-N16 using TUMPA, run: openocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\ @@ -39,7 +39,7 @@ openocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\ } # set default, can be overriden later -adapter_khz 1000 +adapter speed 1000 proc get_partition { name } { global partition_list From 09ac9ab135ed35c846bcec4f7d468c3656852f26 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Mon, 27 Jan 2020 20:10:30 +0200 Subject: [PATCH 112/354] jtag: Fix jtag_reset fallback The fallback provided for the jtag_reset command always fails with a strange message: 'Error: invalid command name "de"' This is caused by incorrect quoting inside the warning message. Fixes: c07b774e8f49 ("jtag: replace command "jtag_reset" with "adapter [de]assert"") Change-Id: Icd47fca2b5a7b33474bfb0040e88193a0968f301 Signed-off-by: Leonard Crestez Reviewed-on: http://openocd.zylin.com/5416 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- src/jtag/startup.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 2ac857158..e522e74d6 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -135,7 +135,7 @@ proc jtag_nsrst_assert_width args { } proc jtag_reset args { - echo "DEPRECATED! use 'adapter [de]assert' not 'jtag_reset'" + echo "DEPRECATED! use 'adapter \[de\]assert' not 'jtag_reset'" switch $args { "0 0" {eval adapter deassert trst deassert srst} From 25f5a8f6be4f717f977ead1af0d819d6b62a5173 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 13 Apr 2019 22:44:45 +0200 Subject: [PATCH 113/354] flash/nor: Export various functions from the CFI core Export various functions needed by other driver, specifically the upcoming Renesas RPC HF driver. No functional change. Change-Id: I551258979a7221288fb4f4382f857db5cfe0b0de Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5148 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/flash/nor/cfi.c | 54 +++++++++++++++++++++++---------------------- src/flash/nor/cfi.h | 21 ++++++++++++++++++ 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index bcb1f575f..224f1749a 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -34,9 +34,6 @@ #include #include -#define CFI_MAX_BUS_WIDTH 4 -#define CFI_MAX_CHIP_WIDTH 4 - /* defines internal maximum size for code fragment in cfi_intel_write_block() */ #define CFI_MAX_INTEL_CODESIZE 256 @@ -112,7 +109,7 @@ static void cfi_fixup(struct flash_bank *bank, const struct cfi_fixup *fixups) } } -static inline uint32_t cfi_flash_address(struct flash_bank *bank, int sector, uint32_t offset) +uint32_t cfi_flash_address(struct flash_bank *bank, int sector, uint32_t offset) { struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -143,8 +140,8 @@ static int cfi_target_write_memory(struct flash_bank *bank, target_addr_t addr, } } -static int cfi_target_read_memory(struct flash_bank *bank, target_addr_t addr, - uint32_t count, uint8_t *buffer) +int cfi_target_read_memory(struct flash_bank *bank, target_addr_t addr, + uint32_t count, uint8_t *buffer) { struct cfi_flash_bank *cfi_info = bank->driver_priv; if (cfi_info->read_mem) { @@ -175,7 +172,7 @@ static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf) } } -static int cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t address) +int cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t address) { uint8_t command[CFI_MAX_BUS_WIDTH]; @@ -298,7 +295,7 @@ static int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, u return ERROR_OK; } -static int cfi_reset(struct flash_bank *bank) +int cfi_reset(struct flash_bank *bank) { struct cfi_flash_bank *cfi_info = bank->driver_priv; int retval = ERROR_OK; @@ -379,7 +376,7 @@ static int cfi_intel_wait_status_busy(struct flash_bank *bank, int timeout, uint return retval; } -static int cfi_spansion_wait_status_busy(struct flash_bank *bank, int timeout) +int cfi_spansion_wait_status_busy(struct flash_bank *bank, int timeout) { uint8_t status, oldstatus; struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -819,14 +816,12 @@ static int cfi_intel_info(struct flash_bank *bank, char *buf, int buf_size) return ERROR_OK; } -/* flash_bank cfi [options] - */ -FLASH_BANK_COMMAND_HANDLER(cfi_flash_bank_command) +int cfi_flash_bank_cmd(struct flash_bank *bank, unsigned int argc, const char **argv) { struct cfi_flash_bank *cfi_info; int bus_swap = 0; - if (CMD_ARGC < 6) + if (argc < 6) return ERROR_COMMAND_SYNTAX_ERROR; /* both widths must: @@ -856,14 +851,14 @@ FLASH_BANK_COMMAND_HANDLER(cfi_flash_bank_command) cfi_info->not_cfi = 0; cfi_info->data_swap = 0; - for (unsigned i = 6; i < CMD_ARGC; i++) { - if (strcmp(CMD_ARGV[i], "x16_as_x8") == 0) + for (unsigned i = 6; i < argc; i++) { + if (strcmp(argv[i], "x16_as_x8") == 0) cfi_info->x16_as_x8 = 1; - else if (strcmp(CMD_ARGV[i], "data_swap") == 0) + else if (strcmp(argv[i], "data_swap") == 0) cfi_info->data_swap = 1; - else if (strcmp(CMD_ARGV[i], "bus_swap") == 0) + else if (strcmp(argv[i], "bus_swap") == 0) bus_swap = 1; - else if (strcmp(CMD_ARGV[i], "jedec_probe") == 0) + else if (strcmp(argv[i], "jedec_probe") == 0) cfi_info->jedec_probe = 1; } @@ -880,6 +875,13 @@ FLASH_BANK_COMMAND_HANDLER(cfi_flash_bank_command) return ERROR_OK; } +/* flash_bank cfi [options] + */ +FLASH_BANK_COMMAND_HANDLER(cfi_flash_bank_command) +{ + return cfi_flash_bank_cmd(bank, CMD_ARGC, CMD_ARGV); +} + static int cfi_intel_erase(struct flash_bank *bank, int first, int last) { int retval; @@ -918,7 +920,7 @@ static int cfi_intel_erase(struct flash_bank *bank, int first, int last) return cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); } -static int cfi_spansion_unlock_seq(struct flash_bank *bank) +int cfi_spansion_unlock_seq(struct flash_bank *bank) { int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -975,7 +977,7 @@ static int cfi_spansion_erase(struct flash_bank *bank, int first, int last) return cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); } -static int cfi_erase(struct flash_bank *bank, int first, int last) +int cfi_erase(struct flash_bank *bank, int first, int last) { struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -1118,7 +1120,7 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la return cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0)); } -static int cfi_protect(struct flash_bank *bank, int set, int first, int last) +int cfi_protect(struct flash_bank *bank, int set, int first, int last) { struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -2220,7 +2222,7 @@ static int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word return ERROR_OK; } -static int cfi_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address) +int cfi_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address) { struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -2591,7 +2593,7 @@ static int cfi_query_string(struct flash_bank *bank, int address) return ERROR_OK; } -static int cfi_probe(struct flash_bank *bank) +int cfi_probe(struct flash_bank *bank) { struct cfi_flash_bank *cfi_info = bank->driver_priv; struct target *target = bank->target; @@ -2927,7 +2929,7 @@ static int cfi_probe(struct flash_bank *bank) return ERROR_OK; } -static int cfi_auto_probe(struct flash_bank *bank) +int cfi_auto_probe(struct flash_bank *bank) { struct cfi_flash_bank *cfi_info = bank->driver_priv; if (cfi_info->probed) @@ -2995,7 +2997,7 @@ static int cfi_spansion_protect_check(struct flash_bank *bank) return cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); } -static int cfi_protect_check(struct flash_bank *bank) +int cfi_protect_check(struct flash_bank *bank) { struct cfi_flash_bank *cfi_info = bank->driver_priv; @@ -3023,7 +3025,7 @@ static int cfi_protect_check(struct flash_bank *bank) return ERROR_OK; } -static int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size) +int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size) { int printed; struct cfi_flash_bank *cfi_info = bank->driver_priv; diff --git a/src/flash/nor/cfi.h b/src/flash/nor/cfi.h index 9451faae6..aef7a04f9 100644 --- a/src/flash/nor/cfi.h +++ b/src/flash/nor/cfi.h @@ -154,6 +154,24 @@ struct cfi_fixup { const void *param; }; +int cfi_erase(struct flash_bank *bank, int first, int last); +int cfi_protect(struct flash_bank *bank, int set, int first, int last); +int cfi_probe(struct flash_bank *bank); +int cfi_auto_probe(struct flash_bank *bank); +int cfi_protect_check(struct flash_bank *bank); +int cfi_get_info(struct flash_bank *bank, char *buf, int buf_size); +int cfi_flash_bank_cmd(struct flash_bank *bank, unsigned int argc, const char **argv); + +uint32_t cfi_flash_address(struct flash_bank *bank, int sector, uint32_t offset); +int cfi_spansion_unlock_seq(struct flash_bank *bank); +int cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t address); +int cfi_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address); +int cfi_spansion_wait_status_busy(struct flash_bank *bank, int timeout); +int cfi_reset(struct flash_bank *bank); + +int cfi_target_read_memory(struct flash_bank *bank, target_addr_t addr, + uint32_t count, uint8_t *buffer); + #define CFI_MFR_AMD 0x0001 #define CFI_MFR_FUJITSU 0x0004 #define CFI_MFR_ATMEL 0x001F @@ -166,4 +184,7 @@ struct cfi_fixup { #define CFI_MFR_ANY 0xffff #define CFI_ID_ANY 0xffff +#define CFI_MAX_BUS_WIDTH 4 +#define CFI_MAX_CHIP_WIDTH 4 + #endif /* OPENOCD_FLASH_NOR_CFI_H */ From c2e2deb4dd8edc7046d0412eef3b1203d7b327a0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 13 Apr 2019 22:44:45 +0200 Subject: [PATCH 114/354] flash/nor: Add Renesas RPC HF driver Add driver for the RPC block in HF mode on Renesas R-Car Gen3 SoCs. This driver allows operating the on-SIP HF memory. Note that HF is CFI compliant flash, but it is not memory mapped, hence the need to replace all the memory accessors and read/write functions. The write function is entirely replaced to increase performance and is Spansion/AMD specific, since there is no known SIP with other HF from another vendor. Add the following two lines to board TCL file to bind the driver on R-Car Gen3 SoC using HyperFlash: set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME rpchf 0x08000000 0x4000000 2 2 $_CHIPNAME.a57.0 Change-Id: Ie18729d017eeb46e1363333ffe002d010dfc5ead Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5149 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/flash/nor/Makefile.am | 1 + src/flash/nor/drivers.c | 2 + src/flash/nor/renesas_rpchf.c | 648 ++++++++++++++++++++++++++++++++++ 3 files changed, 651 insertions(+) create mode 100644 src/flash/nor/renesas_rpchf.c diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index 12bafa2c5..18b3b859b 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -51,6 +51,7 @@ NOR_DRIVERS = \ %D%/psoc4.c \ %D%/psoc5lp.c \ %D%/psoc6.c \ + %D%/renesas_rpchf.c \ %D%/sh_qspi.c \ %D%/sim3x.c \ %D%/spi.c \ diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index fb43a438d..d52e072ee 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -66,6 +66,7 @@ extern const struct flash_driver psoc5lp_flash; extern const struct flash_driver psoc5lp_eeprom_flash; extern const struct flash_driver psoc5lp_nvl_flash; extern const struct flash_driver psoc6_flash; +extern const struct flash_driver renesas_rpchf_flash; extern const struct flash_driver sh_qspi_flash; extern const struct flash_driver sim3x_flash; extern const struct flash_driver stellaris_flash; @@ -137,6 +138,7 @@ static const struct flash_driver * const flash_drivers[] = { &psoc5lp_eeprom_flash, &psoc5lp_nvl_flash, &psoc6_flash, + &renesas_rpchf_flash, &sh_qspi_flash, &sim3x_flash, &stellaris_flash, diff --git a/src/flash/nor/renesas_rpchf.c b/src/flash/nor/renesas_rpchf.c new file mode 100644 index 000000000..3f03f9275 --- /dev/null +++ b/src/flash/nor/renesas_rpchf.c @@ -0,0 +1,648 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Renesas RCar Gen3 RPC Hyperflash driver + * Based on U-Boot RPC Hyperflash driver + * + * Copyright (C) 2016 Renesas Electronics Corporation + * Copyright (C) 2016 Cogent Embedded, Inc. + * Copyright (C) 2017-2019 Marek Vasut + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "imp.h" +#include "cfi.h" +#include "non_cfi.h" +#include +#include +#include + +#define RPC_CMNCR 0x0000 /* R/W */ +#define RPC_CMNCR_MD BIT(31) +#define RPC_CMNCR_MOIIO0(val) (((val) & 0x3) << 16) +#define RPC_CMNCR_MOIIO1(val) (((val) & 0x3) << 18) +#define RPC_CMNCR_MOIIO2(val) (((val) & 0x3) << 20) +#define RPC_CMNCR_MOIIO3(val) (((val) & 0x3) << 22) +#define RPC_CMNCR_MOIIO_HIZ (RPC_CMNCR_MOIIO0(3) | RPC_CMNCR_MOIIO1(3) | \ + RPC_CMNCR_MOIIO2(3) | RPC_CMNCR_MOIIO3(3)) +#define RPC_CMNCR_IO0FV(val) (((val) & 0x3) << 8) +#define RPC_CMNCR_IO2FV(val) (((val) & 0x3) << 12) +#define RPC_CMNCR_IO3FV(val) (((val) & 0x3) << 14) +#define RPC_CMNCR_IOFV_HIZ (RPC_CMNCR_IO0FV(3) | RPC_CMNCR_IO2FV(3) | \ + RPC_CMNCR_IO3FV(3)) +#define RPC_CMNCR_BSZ(val) (((val) & 0x3) << 0) + +#define RPC_SSLDR 0x0004 /* R/W */ +#define RPC_SSLDR_SPNDL(d) (((d) & 0x7) << 16) +#define RPC_SSLDR_SLNDL(d) (((d) & 0x7) << 8) +#define RPC_SSLDR_SCKDL(d) (((d) & 0x7) << 0) + +#define RPC_DRCR 0x000C /* R/W */ +#define RPC_DRCR_SSLN BIT(24) +#define RPC_DRCR_RBURST(v) (((v) & 0x1F) << 16) +#define RPC_DRCR_RCF BIT(9) +#define RPC_DRCR_RBE BIT(8) +#define RPC_DRCR_SSLE BIT(0) + +#define RPC_DRCMR 0x0010 /* R/W */ +#define RPC_DRCMR_CMD(c) (((c) & 0xFF) << 16) +#define RPC_DRCMR_OCMD(c) (((c) & 0xFF) << 0) + +#define RPC_DREAR 0x0014 /* R/W */ +#define RPC_DREAR_EAV(v) (((v) & 0xFF) << 16) +#define RPC_DREAR_EAC(v) (((v) & 0x7) << 0) + +#define RPC_DROPR 0x0018 /* R/W */ +#define RPC_DROPR_OPD3(o) (((o) & 0xFF) << 24) +#define RPC_DROPR_OPD2(o) (((o) & 0xFF) << 16) +#define RPC_DROPR_OPD1(o) (((o) & 0xFF) << 8) +#define RPC_DROPR_OPD0(o) (((o) & 0xFF) << 0) + +#define RPC_DRENR 0x001C /* R/W */ +#define RPC_DRENR_CDB(o) (uint32_t)((((o) & 0x3) << 30)) +#define RPC_DRENR_OCDB(o) (((o) & 0x3) << 28) +#define RPC_DRENR_ADB(o) (((o) & 0x3) << 24) +#define RPC_DRENR_OPDB(o) (((o) & 0x3) << 20) +#define RPC_DRENR_SPIDB(o) (((o) & 0x3) << 16) +#define RPC_DRENR_DME BIT(15) +#define RPC_DRENR_CDE BIT(14) +#define RPC_DRENR_OCDE BIT(12) +#define RPC_DRENR_ADE(v) (((v) & 0xF) << 8) +#define RPC_DRENR_OPDE(v) (((v) & 0xF) << 4) + +#define RPC_SMCR 0x0020 /* R/W */ +#define RPC_SMCR_SSLKP BIT(8) +#define RPC_SMCR_SPIRE BIT(2) +#define RPC_SMCR_SPIWE BIT(1) +#define RPC_SMCR_SPIE BIT(0) + +#define RPC_SMCMR 0x0024 /* R/W */ +#define RPC_SMCMR_CMD(c) (((c) & 0xFF) << 16) +#define RPC_SMCMR_OCMD(c) (((c) & 0xFF) << 0) + +#define RPC_SMADR 0x0028 /* R/W */ +#define RPC_SMOPR 0x002C /* R/W */ +#define RPC_SMOPR_OPD0(o) (((o) & 0xFF) << 0) +#define RPC_SMOPR_OPD1(o) (((o) & 0xFF) << 8) +#define RPC_SMOPR_OPD2(o) (((o) & 0xFF) << 16) +#define RPC_SMOPR_OPD3(o) (((o) & 0xFF) << 24) + +#define RPC_SMENR 0x0030 /* R/W */ +#define RPC_SMENR_CDB(o) (((o) & 0x3) << 30) +#define RPC_SMENR_OCDB(o) (((o) & 0x3) << 28) +#define RPC_SMENR_ADB(o) (((o) & 0x3) << 24) +#define RPC_SMENR_OPDB(o) (((o) & 0x3) << 20) +#define RPC_SMENR_SPIDB(o) (((o) & 0x3) << 16) +#define RPC_SMENR_DME BIT(15) +#define RPC_SMENR_CDE BIT(14) +#define RPC_SMENR_OCDE BIT(12) +#define RPC_SMENR_ADE(v) (((v) & 0xF) << 8) +#define RPC_SMENR_OPDE(v) (((v) & 0xF) << 4) +#define RPC_SMENR_SPIDE(v) (((v) & 0xF) << 0) + +#define RPC_SMRDR0 0x0038 /* R */ +#define RPC_SMRDR1 0x003C /* R */ +#define RPC_SMWDR0 0x0040 /* R/W */ +#define RPC_SMWDR1 0x0044 /* R/W */ +#define RPC_CMNSR 0x0048 /* R */ +#define RPC_CMNSR_SSLF BIT(1) +#define RPC_CMNSR_TEND BIT(0) + +#define RPC_DRDMCR 0x0058 /* R/W */ +#define RPC_DRDMCR_DMCYC(v) (((v) & 0xF) << 0) + +#define RPC_DRDRENR 0x005C /* R/W */ +#define RPC_DRDRENR_HYPE (0x5 << 12) +#define RPC_DRDRENR_ADDRE BIT(8) +#define RPC_DRDRENR_OPDRE BIT(4) +#define RPC_DRDRENR_DRDRE BIT(0) + +#define RPC_SMDMCR 0x0060 /* R/W */ +#define RPC_SMDMCR_DMCYC(v) (((v) & 0xF) << 0) + +#define RPC_SMDRENR 0x0064 /* R/W */ +#define RPC_SMDRENR_HYPE (0x5 << 12) +#define RPC_SMDRENR_ADDRE BIT(8) +#define RPC_SMDRENR_OPDRE BIT(4) +#define RPC_SMDRENR_SPIDRE BIT(0) + +#define RPC_PHYCNT 0x007C /* R/W */ +#define RPC_PHYCNT_CAL BIT(31) +#define PRC_PHYCNT_OCTA_AA BIT(22) +#define PRC_PHYCNT_OCTA_SA BIT(23) +#define PRC_PHYCNT_EXDS BIT(21) +#define RPC_PHYCNT_OCT BIT(20) +#define RPC_PHYCNT_WBUF2 BIT(4) +#define RPC_PHYCNT_WBUF BIT(2) +#define RPC_PHYCNT_MEM(v) (((v) & 0x3) << 0) + +#define RPC_PHYINT 0x0088 /* R/W */ +#define RPC_PHYINT_RSTEN BIT(18) +#define RPC_PHYINT_WPEN BIT(17) +#define RPC_PHYINT_INTEN BIT(16) +#define RPC_PHYINT_RST BIT(2) +#define RPC_PHYINT_WP BIT(1) +#define RPC_PHYINT_INT BIT(0) + +#define RPC_WBUF 0x8000 /* R/W size=4/8/16/32/64Bytes */ +#define RPC_WBUF_SIZE 0x100 + +static uint32_t rpc_base = 0xee200000; +static uint32_t mem_base = 0x08000000; + +enum rpc_hf_size { + RPC_HF_SIZE_16BIT = RPC_SMENR_SPIDE(0x8), + RPC_HF_SIZE_32BIT = RPC_SMENR_SPIDE(0xC), + RPC_HF_SIZE_64BIT = RPC_SMENR_SPIDE(0xF), +}; + +static int rpc_hf_wait_tend(struct target *target) +{ + uint32_t reg = rpc_base + RPC_CMNSR; + uint32_t val; + unsigned long timeout = 1000; + long long endtime; + int ret; + + endtime = timeval_ms() + timeout; + do { + ret = target_read_u32(target, reg, &val); + if (ret != ERROR_OK) + return ERROR_FAIL; + + if (val & RPC_CMNSR_TEND) + return ERROR_OK; + + alive_sleep(1); + } while (timeval_ms() < endtime); + + LOG_ERROR("timeout"); + return ERROR_TIMEOUT_REACHED; +} + +static int clrsetbits_u32(struct target *target, uint32_t reg, + uint32_t clr, uint32_t set) +{ + uint32_t val; + int ret; + + ret = target_read_u32(target, reg, &val); + if (ret != ERROR_OK) + return ret; + + val &= ~clr; + val |= set; + + return target_write_u32(target, reg, val); +} + +static int rpc_hf_mode(struct target *target, bool manual) +{ + uint32_t val; + int ret; + + ret = rpc_hf_wait_tend(target); + if (ret != ERROR_OK) { + LOG_ERROR("Mode TEND timeout"); + return ret; + } + + ret = clrsetbits_u32(target, rpc_base + RPC_PHYCNT, + RPC_PHYCNT_WBUF | RPC_PHYCNT_WBUF2 | + RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3), + RPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3)); + if (ret != ERROR_OK) + return ret; + + ret = clrsetbits_u32(target, rpc_base + RPC_CMNCR, + RPC_CMNCR_MD | RPC_CMNCR_BSZ(3), + RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ | + (manual ? RPC_CMNCR_MD : 0) | RPC_CMNCR_BSZ(1)); + if (ret != ERROR_OK) + return ret; + + if (manual) + return ERROR_OK; + + ret = target_write_u32(target, rpc_base + RPC_DRCR, + RPC_DRCR_RBURST(0x1F) | RPC_DRCR_RCF | + RPC_DRCR_RBE); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, rpc_base + RPC_DRCMR, + RPC_DRCMR_CMD(0xA0)); + if (ret != ERROR_OK) + return ret; + ret = target_write_u32(target, rpc_base + RPC_DRENR, + RPC_DRENR_CDB(2) | RPC_DRENR_OCDB(2) | + RPC_DRENR_ADB(2) | RPC_DRENR_SPIDB(2) | + RPC_DRENR_CDE | RPC_DRENR_OCDE | + RPC_DRENR_ADE(4)); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, rpc_base + RPC_DRDMCR, + RPC_DRDMCR_DMCYC(0xE)); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, rpc_base + RPC_DRDRENR, + RPC_DRDRENR_HYPE | RPC_DRDRENR_ADDRE | + RPC_DRDRENR_DRDRE); + if (ret != ERROR_OK) + return ret; + + /* Dummy read */ + return target_read_u32(target, rpc_base + RPC_DRCR, &val); +} + +static int rpc_hf_xfer(struct target *target, target_addr_t addr, + uint32_t wdata, uint32_t *rdata, enum rpc_hf_size size, + bool write, const uint8_t *wbuf, unsigned int wbuf_size) +{ + int ret; + uint32_t val; + + if (wbuf_size != 0) { + ret = rpc_hf_wait_tend(target); + if (ret != ERROR_OK) { + LOG_ERROR("Xfer TEND timeout"); + return ret; + } + + /* Write calibration magic */ + ret = target_write_u32(target, rpc_base + RPC_DRCR, 0x01FF0301); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, rpc_base + RPC_PHYCNT, 0x80030277); + if (ret != ERROR_OK) + return ret; + + ret = target_write_memory(target, rpc_base | RPC_WBUF, 4, + wbuf_size / 4, wbuf); + if (ret != ERROR_OK) + return ret; + + ret = clrsetbits_u32(target, rpc_base + RPC_CMNCR, + RPC_CMNCR_MD | RPC_CMNCR_BSZ(3), + RPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ | + RPC_CMNCR_MD | RPC_CMNCR_BSZ(1)); + if (ret != ERROR_OK) + return ret; + } else { + ret = rpc_hf_mode(target, 1); + if (ret != ERROR_OK) + return ret; + } + + /* Submit HF address, SMCMR CMD[7] ~= CA Bit# 47 (R/nW) */ + ret = target_write_u32(target, rpc_base + RPC_SMCMR, + write ? 0 : RPC_SMCMR_CMD(0x80)); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, rpc_base + RPC_SMADR, + addr >> 1); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, rpc_base + RPC_SMOPR, 0x0); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, rpc_base + RPC_SMDRENR, + RPC_SMDRENR_HYPE | RPC_SMDRENR_ADDRE | + RPC_SMDRENR_SPIDRE); + if (ret != ERROR_OK) + return ret; + + val = RPC_SMENR_CDB(2) | RPC_SMENR_OCDB(2) | + RPC_SMENR_ADB(2) | RPC_SMENR_SPIDB(2) | + (wbuf_size ? RPC_SMENR_OPDB(2) : 0) | + RPC_SMENR_CDE | RPC_SMENR_OCDE | RPC_SMENR_ADE(4) | size; + + if (write) { + ret = target_write_u32(target, rpc_base + RPC_SMENR, val); + if (ret != ERROR_OK) + return ret; + + if (wbuf_size == 0) { + buf_bswap32((uint8_t *)&wdata, (uint8_t *)&wdata, 4); + ret = target_write_u32(target, rpc_base + RPC_SMWDR0, + wdata); + if (ret != ERROR_OK) + return ret; + } + + ret = target_write_u32(target, rpc_base + RPC_SMCR, + RPC_SMCR_SPIWE | RPC_SMCR_SPIE); + if (ret != ERROR_OK) + return ret; + } else { + val |= RPC_SMENR_DME; + + ret = target_write_u32(target, rpc_base + RPC_SMDMCR, + RPC_SMDMCR_DMCYC(0xE)); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, rpc_base + RPC_SMENR, val); + if (ret != ERROR_OK) + return ret; + + ret = target_write_u32(target, rpc_base + RPC_SMCR, + RPC_SMCR_SPIRE | RPC_SMCR_SPIE); + if (ret != ERROR_OK) + return ret; + + ret = rpc_hf_wait_tend(target); + if (ret != ERROR_OK) + return ret; + + uint32_t val32; + ret = target_read_u32(target, rpc_base + RPC_SMRDR0, &val32); + if (ret != ERROR_OK) + return ret; + buf_bswap32((uint8_t *)&val32, (uint8_t *)&val32, 4); + *rdata = val32; + } + + ret = rpc_hf_mode(target, 0); + if (ret != ERROR_OK) + LOG_ERROR("Xfer done TEND timeout"); + return ret; +} + +static int rpchf_target_write_memory(struct flash_bank *bank, target_addr_t addr, + uint32_t count, const uint8_t *buffer) +{ + struct target *target = bank->target; + uint32_t wdata; + + if (count != 2) + return ERROR_FAIL; + + wdata = buffer[0] | (buffer[1] << 8); + + return rpc_hf_xfer(target, addr, wdata, NULL, RPC_HF_SIZE_16BIT, + true, NULL, 0); +} + +static int rpchf_target_read_memory(struct flash_bank *bank, target_addr_t addr, + uint32_t count, uint8_t *buffer) +{ + struct target *target = bank->target; + uint32_t i, rdata; + int ret; + + for (i = 0; i < count; i++) { + ret = rpc_hf_xfer(target, addr + (2 * i), 0, &rdata, + RPC_HF_SIZE_16BIT, false, NULL, 0); + if (ret != ERROR_OK) + return ret; + buffer[(2 * i) + 0] = rdata & 0xff; + buffer[(2 * i) + 1] = (rdata >> 8) & 0xff; + } + + return ERROR_OK; +} + +FLASH_BANK_COMMAND_HANDLER(rpchf_flash_bank_command) +{ + struct cfi_flash_bank *cfi_info; + int ret; + + ret = cfi_flash_bank_cmd(bank, CMD_ARGC, CMD_ARGV); + if (ret != ERROR_OK) + return ret; + + cfi_info = bank->driver_priv; + cfi_info->read_mem = rpchf_target_read_memory; + cfi_info->write_mem = rpchf_target_write_memory; + + return ERROR_OK; +} + +static int rpchf_spansion_write_words(struct flash_bank *bank, const uint8_t *word, + uint32_t wordcount, uint32_t address) +{ + int retval; + struct cfi_flash_bank *cfi_info = bank->driver_priv; + struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; + + /* Calculate buffer size and boundary mask + * buffersize is (buffer size per chip) * (number of chips) + * bufferwsize is buffersize in words */ + uint32_t buffersize = RPC_WBUF_SIZE; + uint32_t buffermask = buffersize - 1; + uint32_t bufferwsize = buffersize / 2; + + /* Check for valid range */ + if (address & buffermask) { + LOG_ERROR("Write address at base " TARGET_ADDR_FMT + ", address 0x%" PRIx32 " not aligned to 2^%d boundary", + bank->base, address, cfi_info->max_buf_write_size); + return ERROR_FLASH_OPERATION_FAILED; + } + + /* Check for valid size */ + if (wordcount > bufferwsize) { + LOG_ERROR("Number of data words %" PRId32 " exceeds available buffersize %" + PRId32, wordcount, buffersize); + return ERROR_FLASH_OPERATION_FAILED; + } + + /* Unlock */ + retval = cfi_spansion_unlock_seq(bank); + if (retval != ERROR_OK) + return retval; + + retval = cfi_send_command(bank, 0xa0, cfi_flash_address(bank, 0, pri_ext->_unlock1)); + if (retval != ERROR_OK) + return retval; + + retval = rpc_hf_xfer(bank->target, address, 0, NULL, RPC_HF_SIZE_64BIT, true, word, wordcount * 2); + if (retval != ERROR_OK) + return retval; + + if (cfi_spansion_wait_status_busy(bank, cfi_info->word_write_timeout) != ERROR_OK) { + retval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0)); + if (retval != ERROR_OK) + return retval; + + LOG_ERROR("couldn't write block at base " TARGET_ADDR_FMT + ", address 0x%" PRIx32 ", size 0x%" PRIx32, bank->base, address, + bufferwsize); + return ERROR_FLASH_OPERATION_FAILED; + } + + return ERROR_OK; +} + +static int rpchf_write_words(struct flash_bank *bank, const uint8_t *word, + uint32_t wordcount, uint32_t address) +{ + return rpchf_spansion_write_words(bank, word, wordcount, address); +} + +static int rpchf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) +{ + struct cfi_flash_bank *cfi_info = bank->driver_priv; + uint32_t address = bank->base + offset; /* address of first byte to be programmed */ + uint32_t write_p; + int align; /* number of unaligned bytes */ + uint8_t current_word[CFI_MAX_BUS_WIDTH * 4]; /* word (bus_width size) currently being + *programmed */ + int i; + int retval; + + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (offset + count > bank->size) + return ERROR_FLASH_DST_OUT_OF_BANK; + + if (cfi_info->qry[0] != 'Q') + return ERROR_FLASH_BANK_NOT_PROBED; + + /* start at the first byte of the first word (bus_width size) */ + write_p = address & ~(bank->bus_width - 1); + align = address - write_p; + if (align != 0) { + LOG_INFO("Fixup %d unaligned head bytes", align); + + /* read a complete word from flash */ + retval = cfi_target_read_memory(bank, write_p, 1, current_word); + if (retval != ERROR_OK) + return retval; + + /* replace only bytes that must be written */ + for (i = align; + (i < bank->bus_width) && (count > 0); + i++, count--) + if (cfi_info->data_swap) + /* data bytes are swapped (reverse endianness) */ + current_word[bank->bus_width - i] = *buffer++; + else + current_word[i] = *buffer++; + + retval = cfi_write_word(bank, current_word, write_p); + if (retval != ERROR_OK) + return retval; + write_p += bank->bus_width; + } + + /* Calculate buffer size and boundary mask + * buffersize is (buffer size per chip) * (number of chips) + * bufferwsize is buffersize in words */ + uint32_t buffersize = RPC_WBUF_SIZE; + uint32_t buffermask = buffersize-1; + uint32_t bufferwsize = buffersize / bank->bus_width; + + /* fall back to memory writes */ + while (count >= (uint32_t)bank->bus_width) { + int fallback; + if ((write_p & 0xff) == 0) { + LOG_INFO("Programming at 0x%08" PRIx32 ", count 0x%08" + PRIx32 " bytes remaining", write_p, count); + } + fallback = 1; + if ((bufferwsize > 0) && (count >= buffersize) && + !(write_p & buffermask)) { + retval = rpchf_write_words(bank, buffer, bufferwsize, write_p); + if (retval == ERROR_OK) { + buffer += buffersize; + write_p += buffersize; + count -= buffersize; + fallback = 0; + } else if (retval != ERROR_FLASH_OPER_UNSUPPORTED) + return retval; + } + /* try the slow way? */ + if (fallback) { + for (i = 0; i < bank->bus_width; i++) + current_word[i] = *buffer++; + + retval = cfi_write_word(bank, current_word, write_p); + if (retval != ERROR_OK) + return retval; + + write_p += bank->bus_width; + count -= bank->bus_width; + } + } + + /* return to read array mode, so we can read from flash again for padding */ + retval = cfi_reset(bank); + if (retval != ERROR_OK) + return retval; + + /* handle unaligned tail bytes */ + if (count > 0) { + LOG_INFO("Fixup %" PRId32 " unaligned tail bytes", count); + + /* read a complete word from flash */ + retval = cfi_target_read_memory(bank, write_p, 1, current_word); + if (retval != ERROR_OK) + return retval; + + /* replace only bytes that must be written */ + for (i = 0; (i < bank->bus_width) && (count > 0); i++, count--) + if (cfi_info->data_swap) + /* data bytes are swapped (reverse endianness) */ + current_word[bank->bus_width - i] = *buffer++; + else + current_word[i] = *buffer++; + + retval = cfi_write_word(bank, current_word, write_p); + if (retval != ERROR_OK) + return retval; + } + + /* return to read array mode */ + return cfi_reset(bank); +} + +static int rpchf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count) +{ + struct cfi_flash_bank *cfi_info = bank->driver_priv; + struct target *target = bank->target; + + LOG_DEBUG("reading buffer of %" PRIi32 " byte at 0x%8.8" PRIx32, + count, offset); + + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (offset + count > bank->size) + return ERROR_FLASH_DST_OUT_OF_BANK; + + if (cfi_info->qry[0] != 'Q') + return ERROR_FLASH_BANK_NOT_PROBED; + + return target_read_memory(target, offset | mem_base, + 4, count / 4, buffer); +} + +const struct flash_driver renesas_rpchf_flash = { + .name = "rpchf", + .flash_bank_command = rpchf_flash_bank_command, + .erase = cfi_erase, + .protect = cfi_protect, + .write = rpchf_write, + .read = rpchf_read, + .probe = cfi_probe, + .auto_probe = cfi_auto_probe, + .erase_check = default_flash_blank_check, + .protect_check = cfi_protect_check, + .info = cfi_get_info, + .free_driver_priv = default_flash_free_driver_priv, +}; From d91e19eb16b0ba387e270da9a6001dfdc3482524 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 5 Feb 2020 18:00:12 +0100 Subject: [PATCH 115/354] jtag: drivers: xlnx-pcie-xvc: fix build on Linux pre v4.10 The macro PCI_CFG_SPACE_EXP_SIZE is exposed to userspace from Linux kernel v4.10, with commit cc10385b6fde ("PCI: Move config space size macros to pci_regs.h") http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc10385b6fde Define the macro in the driver code, if not already defined. Change-Id: I610219a2587eff2c142102b9f7830e3da882af78 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5435 Reviewed-by: Moritz Fischer Reviewed-by: Tarek BOCHKATI Tested-by: jenkins --- src/jtag/drivers/xlnx-pcie-xvc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/jtag/drivers/xlnx-pcie-xvc.c b/src/jtag/drivers/xlnx-pcie-xvc.c index 48b03ec83..17438593a 100644 --- a/src/jtag/drivers/xlnx-pcie-xvc.c +++ b/src/jtag/drivers/xlnx-pcie-xvc.c @@ -20,6 +20,11 @@ #include #include +/* Available only from kernel v4.10 */ +#ifndef PCI_CFG_SPACE_EXP_SIZE +#define PCI_CFG_SPACE_EXP_SIZE 4096 +#endif + #define PCIE_EXT_CAP_LST 0x100 #define XLNX_XVC_EXT_CAP 0x00 From b4dc07388181addb14980f45251ae26c0be6d34e Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Fri, 28 Jun 2019 15:45:23 +0200 Subject: [PATCH 116/354] tcl: Add interface config for isodebug isolated JTAG/SWD+UART Currently only used internally at Unjo. Change-Id: I7786e95e1bd755a73156ecad5b6d7f6273d8ddef Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/5251 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/interface/ftdi/isodebug.cfg | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tcl/interface/ftdi/isodebug.cfg diff --git a/tcl/interface/ftdi/isodebug.cfg b/tcl/interface/ftdi/isodebug.cfg new file mode 100644 index 000000000..ead28644c --- /dev/null +++ b/tcl/interface/ftdi/isodebug.cfg @@ -0,0 +1,27 @@ +# isodebug v1 +# 5 kV isolated JTAG/SWD + UART adapter by Unjo AB + +adapter driver ftdi +ftdi_vid_pid 0x22b7 0x150d + +ftdi_layout_init 0x0ff8 0xfffb + +ftdi_layout_signal LED -ndata 0x0100 +ftdi_layout_signal nTRST -data 0x0200 +ftdi_layout_signal nSRST -noe 0x0400 +ftdi_layout_signal SWDIO_OE -data 0x0008 + +# Mode signals, either of these needs to be high to drive the JTAG/SWD pins. +# The power-on state is low for both signals but the init setting above sets +# JTAG_EN high. +ftdi_layout_signal SWD_EN -data 0x1000 +ftdi_layout_signal JTAG_EN -data 0x0800 + +# In SWD mode, the JTAG_EN signal doubles as SWO_EN_N which switches the +# second FTDI channel UART RxD to the SWO pin instead of the separate RxD +# pin. Note that the default init state has this pin high so when OpenOCD +# starts in SWD mode, SWO is by default disabled. To enable SWO tracing, +# issue the command 'ftdi_set_signal SWO_EN 1' where tracing is configured. +# To switch back to using the separate UART, SWO_EN needs to be disabled +# before exiting OpenOCD, or the adapter replugged. +ftdi_layout_signal SWO_EN -nalias JTAG_EN From 095809648ba2aa018adef7a6ff75e9eaf2bb26bb Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 30 Jan 2020 18:11:54 +0100 Subject: [PATCH 117/354] tcl: fix remaining scripts after rework adapter commands Some script have been added or modified after the patches for reworking the adapter commands were pushed in gerrit. Such scripts use the old command syntax and trigger a "deprecated" warning at runtime. Fix them with the same sed commands used for the other scripts: sed -i 's/^interface /adapter driver /' $(find tcl/ -type f) sed -i 's/adapter_khz/adapter speed/g' $(find tcl/ -type f) sed -i 's/adapter_nsrst_delay/adapter srst delay/g' $(find tcl/ -type f) sed -i 's/adapter_nsrst_assert_width/adapter srst pulse_width/g' $(find tcl/ -type f) Change-Id: I0824d6c506a9af3eb9129b74c02a92b4eb1b100d Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5424 Reviewed-by: Oleksij Rempel Tested-by: jenkins --- tcl/board/rigado_bmd300_ek.cfg | 2 +- tcl/interface/stlink-dap.cfg | 2 +- tcl/target/infineon/tle987x.cfg | 2 +- tcl/target/stm32wbx.cfg | 8 ++++---- tcl/target/swm050.cfg | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tcl/board/rigado_bmd300_ek.cfg b/tcl/board/rigado_bmd300_ek.cfg index 04e5e1f45..8e1e65ed0 100644 --- a/tcl/board/rigado_bmd300_ek.cfg +++ b/tcl/board/rigado_bmd300_ek.cfg @@ -6,6 +6,6 @@ source [find interface/jlink.cfg] transport select swd -adapter_khz 1000 +adapter speed 1000 source [find target/nrf52.cfg] diff --git a/tcl/interface/stlink-dap.cfg b/tcl/interface/stlink-dap.cfg index f889f74ed..4576ad388 100644 --- a/tcl/interface/stlink-dap.cfg +++ b/tcl/interface/stlink-dap.cfg @@ -6,7 +6,7 @@ # Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support this method # -interface st-link +adapter driver st-link st-link vid_pid 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 # transport select dapdirect_jtag diff --git a/tcl/target/infineon/tle987x.cfg b/tcl/target/infineon/tle987x.cfg index 00cb1c034..84cc2380b 100644 --- a/tcl/target/infineon/tle987x.cfg +++ b/tcl/target/infineon/tle987x.cfg @@ -33,4 +33,4 @@ if { ![using_hla] } { cortex_m reset_config sysresetreq } -adapter_khz 1000 +adapter speed 1000 diff --git a/tcl/target/stm32wbx.cfg b/tcl/target/stm32wbx.cfg index 138bcf186..90f53bb96 100644 --- a/tcl/target/stm32wbx.cfg +++ b/tcl/target/stm32wbx.cfg @@ -55,9 +55,9 @@ flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME # # Note that there is a pretty wide band where things are # more or less stable, see http://openocd.zylin.com/#/c/3366/ -adapter_khz 500 +adapter speed 500 -adapter_nsrst_delay 100 +adapter srst delay 100 if {[using_jtag]} { jtag_ntrst_delay 100 } @@ -77,12 +77,12 @@ $_TARGETNAME configure -event reset-init { mmw 0x58004000 0x00000102 0 ;# FLASH_ACR |= PRFTBE | 2(Latency) mmw 0x58000000 0x00000091 0 ;# RCC_CR = MSI_ON | MSI Range 24 MHz # Boost JTAG frequency - adapter_khz 4000 + adapter speed 4000 } $_TARGETNAME configure -event reset-start { # Reset clock is MSI (4 MHz) - adapter_khz 500 + adapter speed 500 } $_TARGETNAME configure -event examine-end { diff --git a/tcl/target/swm050.cfg b/tcl/target/swm050.cfg index 2c4ab34fe..e6f2ecbf9 100644 --- a/tcl/target/swm050.cfg +++ b/tcl/target/swm050.cfg @@ -29,7 +29,7 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME -adapter_khz 1000 +adapter speed 1000 $_TARGETNAME configure -event reset-init { # Stop the watchdog, just to be safe From 7d6156fae8a398a3bd17af5a30b32a8bf6ec206a Mon Sep 17 00:00:00 2001 From: Christopher Head Date: Tue, 21 Jan 2020 12:44:46 -0800 Subject: [PATCH 118/354] Switch to HTTPS for submodules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit repo.or.cz already redirects HTTP requests to HTTPS. There is therefore no possible benefit to keeping the submodule URLs using HTTP—anyone who can’t access via HTTPS will fail anyway, immediately after the redirect. Changing the submodule URLs eliminates one unnecessary HTTP request and, more importantly, eliminates SSLStrip-style attacks. Change-Id: I9faf1ec8aa87bcfd1acafe2c445a0baf2abfbd09 Signed-off-by: Christopher Head Reviewed-on: http://openocd.zylin.com/5406 Reviewed-by: Antonio Borneo Tested-by: jenkins Reviewed-by: Tomas Vanek --- .gitmodules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 5865ff92a..958c5d901 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ [submodule "tools/git2cl"] path = tools/git2cl - url = http://repo.or.cz/r/git2cl.git + url = https://repo.or.cz/git2cl.git [submodule "jimtcl"] path = jimtcl - url = http://repo.or.cz/r/jimtcl.git + url = https://repo.or.cz/jimtcl.git [submodule "src/jtag/drivers/libjaylink"] path = src/jtag/drivers/libjaylink - url = http://repo.or.cz/r/libjaylink.git + url = https://repo.or.cz/libjaylink.git From 7da165a11f971768be8a56ea9fc49662e133a3d5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 2 Oct 2019 18:21:05 +0200 Subject: [PATCH 119/354] jtag: flush jtag queue after jtag_add_tlr() If the TLR sequence is sent as result of the command "adapter assert trst" while polling is off, the TLR sequence is not sent out until a following jtag operation. Flush the jtag queue before return. Change-Id: I20efd7137cb7b1d1c4f73c1362cbe4e57aeaae49 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5405 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/jtag/core.c b/src/jtag/core.c index 24d645a49..1d59712d1 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -842,6 +842,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst) if (trst_with_tlr) { LOG_DEBUG("JTAG reset with TLR instead of TRST"); jtag_add_tlr(); + jtag_execute_queue(); } else if (jtag_trst != new_trst) { jtag_trst = new_trst; From 324a45e02982b7c8cba641bab69741b944f1e10b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 Jan 2020 12:35:17 +0100 Subject: [PATCH 120/354] stlink: fix max packet size for 8 bit R/W on stlink-v3 While ST internal documentation for STLINK-V3 reports that 8 bits read/write commands handle 512 bytes of data, a firmware bug makes it crashing on high data size. This is fixed with firmware V3J6 (shipped together with V2J36). Check for firmware version to use the proper data size. Change-Id: Iaba6cd26bbe130097c1c19de610680e0e8b69bfc Signed-off-by: Antonio Borneo Fixes: https://sourceforge.net/p/openocd/tickets/259/ Reviewed-on: http://openocd.zylin.com/5408 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/drivers/stlink_usb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 8e4493ed8..dc2fe8c5a 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -78,7 +78,7 @@ /* * ST-Link/V1, ST-Link/V2 and ST-Link/V2.1 are full-speed USB devices and * this limits the bulk packet size and the 8bit read/writes to max 64 bytes. - * STLINK-V3 is a high speed USB 2.0 and the limit is 512 bytes. + * STLINK-V3 is a high speed USB 2.0 and the limit is 512 bytes from FW V3J6. */ #define STLINK_MAX_RW8 (64) #define STLINKV3_MAX_RW8 (512) @@ -317,6 +317,7 @@ enum stlink_mode { #define STLINK_F_QUIRK_JTAG_DP_READ BIT(6) #define STLINK_F_HAS_AP_INIT BIT(7) #define STLINK_F_HAS_DPBANKSEL BIT(8) +#define STLINK_F_HAS_RW8_512BYTES BIT(9) /* aliases */ #define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE @@ -367,7 +368,7 @@ static unsigned int stlink_usb_block(void *handle) assert(handle != NULL); - if (h->version.stlink == 3) + if (h->version.flags & STLINK_F_HAS_RW8_512BYTES) return STLINKV3_MAX_RW8; else return STLINK_MAX_RW8; @@ -1060,6 +1061,10 @@ static int stlink_usb_version(void *handle) if (h->version.jtag >= 2) flags |= STLINK_F_HAS_DPBANKSEL; + /* 8bit read/write max packet size 512 bytes from V3J6 */ + if (h->version.jtag >= 6) + flags |= STLINK_F_HAS_RW8_512BYTES; + break; default: break; From d51cec275c9b15f1d5a5b76ea30d5689db3b8edd Mon Sep 17 00:00:00 2001 From: Frank Hunleth Date: Tue, 17 Dec 2019 15:06:09 -0500 Subject: [PATCH 121/354] efm32: add EFR32ZG13P and EFR32ZG14P parts This adds the EFR32 Zen Gecko Family parts. The device family values are found in table 4.7.11 of https://www.silabs.com/documents/public/reference-manuals/efr32xg14-rm.pdf. Change-Id: I3858b7ba815784b1150e2214a2833e8ff7d249e1 Signed-off-by: Frank Hunleth Reviewed-on: http://openocd.zylin.com/5364 Tested-by: jenkins Reviewed-by: Marc Schink --- src/flash/nor/efm32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c index 245f856b5..479e0d475 100644 --- a/src/flash/nor/efm32.c +++ b/src/flash/nor/efm32.c @@ -140,6 +140,7 @@ static const struct efm32_family_data efm32_families[] = { { 43, "EFR32BG13P Blue", .series = 1 }, { 44, "EFR32BG13B Blue", .series = 1 }, { 45, "EFR32BG13V Blue", .series = 1 }, + { 46, "EFR32ZG13P Zen", .series = 1 }, { 49, "EFR32FG13P Flex", .series = 1 }, { 50, "EFR32FG13B Flex", .series = 1 }, { 51, "EFR32FG13V Flex", .series = 1 }, @@ -149,6 +150,7 @@ static const struct efm32_family_data efm32_families[] = { { 55, "EFR32BG14P Blue", .series = 1 }, { 56, "EFR32BG14B Blue", .series = 1 }, { 57, "EFR32BG14V Blue", .series = 1 }, + { 58, "EFR32ZG14P Zen", .series = 1 }, { 61, "EFR32FG14P Flex", .series = 1 }, { 62, "EFR32FG14B Flex", .series = 1 }, { 63, "EFR32FG14V Flex", .series = 1 }, From b27173d56329ac1c7a7b399110b004e98a9cd8d7 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Tue, 28 Jan 2020 14:54:19 +0100 Subject: [PATCH 122/354] tcl: Remove executable bit Change-Id: Ib452435b13c3cb8d14453d983151936238b9601d Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5419 Reviewed-by: Paul Fertser Tested-by: Paul Fertser Reviewed-by: Antonio Borneo --- tcl/board/dk-tm4c129.cfg | 0 tcl/board/stm32f7discovery.cfg | 0 tcl/target/aducm360.cfg | 0 tcl/target/cc2538.cfg | 0 tcl/target/k1921vk01t.cfg | 0 tcl/target/sim3x.cfg | 0 tcl/target/stm32f7x.cfg | 0 tcl/target/ti-cjtag.cfg | 0 tcl/test/selftest.cfg | 0 9 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 tcl/board/dk-tm4c129.cfg mode change 100755 => 100644 tcl/board/stm32f7discovery.cfg mode change 100755 => 100644 tcl/target/aducm360.cfg mode change 100755 => 100644 tcl/target/cc2538.cfg mode change 100755 => 100644 tcl/target/k1921vk01t.cfg mode change 100755 => 100644 tcl/target/sim3x.cfg mode change 100755 => 100644 tcl/target/stm32f7x.cfg mode change 100755 => 100644 tcl/target/ti-cjtag.cfg mode change 100755 => 100644 tcl/test/selftest.cfg diff --git a/tcl/board/dk-tm4c129.cfg b/tcl/board/dk-tm4c129.cfg old mode 100755 new mode 100644 diff --git a/tcl/board/stm32f7discovery.cfg b/tcl/board/stm32f7discovery.cfg old mode 100755 new mode 100644 diff --git a/tcl/target/aducm360.cfg b/tcl/target/aducm360.cfg old mode 100755 new mode 100644 diff --git a/tcl/target/cc2538.cfg b/tcl/target/cc2538.cfg old mode 100755 new mode 100644 diff --git a/tcl/target/k1921vk01t.cfg b/tcl/target/k1921vk01t.cfg old mode 100755 new mode 100644 diff --git a/tcl/target/sim3x.cfg b/tcl/target/sim3x.cfg old mode 100755 new mode 100644 diff --git a/tcl/target/stm32f7x.cfg b/tcl/target/stm32f7x.cfg old mode 100755 new mode 100644 diff --git a/tcl/target/ti-cjtag.cfg b/tcl/target/ti-cjtag.cfg old mode 100755 new mode 100644 diff --git a/tcl/test/selftest.cfg b/tcl/test/selftest.cfg old mode 100755 new mode 100644 From 853a05287c987d419440b21e2b22f5ab75297739 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 8 Feb 2020 08:58:53 +0100 Subject: [PATCH 123/354] jtag: Fix copy-paste error in 'irscan' help Replace "Instruction Register (DR)" with "Instruction Register (IR)", that is sed "s@DR@IR@", which was likely a copy-paste error. Change-Id: I3e625872c855d655485b3efa5f50fe1c00ecbf52 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5446 Reviewed-by: Tomas Vanek Tested-by: jenkins --- src/jtag/tcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index ef0cd3f53..ba0cb1d1e 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -1314,7 +1314,7 @@ static const struct command_registration jtag_command_handlers[] = { .name = "irscan", .handler = handle_irscan_command, .mode = COMMAND_EXEC, - .help = "Execute Instruction Register (DR) scan. The " + .help = "Execute Instruction Register (IR) scan. The " "specified opcodes are put into each TAP's IR, " "and other TAPs are put in BYPASS.", .usage = "[tap_name instruction]* ['-endstate' state_name]", From 6dfcc3f5a5b7101d9d44312e6a96e0bea05a558d Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Wed, 5 Feb 2020 18:21:15 +0100 Subject: [PATCH 124/354] flash/startup.tcl: update stm32 flash driver aliases This will enable us to use either name when calling flash driver commands. For example the stm32wbx family use the same flash driver as the stm32l4x, so the user has to use 'stm32l4x lock 0' which can be confusing. Now the user can also use 'stm32wbx lock 0' with the same result. Change-Id: Ic0d8da9afc202d7cc82d9b9949827e958a1cc824 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5436 Tested-by: jenkins Reviewed-by: Marc Schink Reviewed-by: Tomas Vanek --- src/flash/startup.tcl | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl index de52e2060..63151b50e 100644 --- a/src/flash/startup.tcl +++ b/src/flash/startup.tcl @@ -101,23 +101,16 @@ proc program {filename args} { add_help_text program "write an image to flash, address is only required for binary images. verify, reset, exit are optional" add_usage_text program " \[address\] \[pre-verify\] \[verify\] \[reset\] \[exit\]" -# stm32f0x uses the same flash driver as the stm32f1x -# this alias enables the use of either name. -proc stm32f0x args { - eval stm32f1x $args -} +# stm32[f0x|f3x] uses the same flash driver as the stm32f1x +proc stm32f0x args { eval stm32f1x $args } +proc stm32f3x args { eval stm32f1x $args } -# stm32f3x uses the same flash driver as the stm32f1x -# this alias enables the use of either name. -proc stm32f3x args { - eval stm32f1x $args -} +# stm32[f4x|f7x] uses the same flash driver as the stm32f2x +proc stm32f4x args { eval stm32f2x $args } +proc stm32f7x args { eval stm32f2x $args } -# stm32f4x uses the same flash driver as the stm32f2x -# this alias enables the use of either name. -proc stm32f4x args { - eval stm32f2x $args -} +# stm32wb uses the same flash driver as the stm32l4x +proc stm32wbx args { eval stm32l4x $args } # ease migration to updated flash driver proc stm32x args { From 0a11537b3220749107f4ec78c76236ac8c9339d1 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Wed, 5 Feb 2020 19:00:46 +0100 Subject: [PATCH 125/354] flash/stm32lx: mention explicitly that this driver covers STM32 L0 and L1 this is to avoid confusion with STM32 L4, L4+ and L5 families also: - a warning message is changed to error - stm32l0x and stm32l1x aliases has been created to permit the usage of either names Change-Id: If3f16d2a3b7d1369959aa7407da37a9076ea91d7 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5437 Reviewed-by: Marc Schink Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 2 +- src/flash/nor/stm32lx.c | 2 +- src/flash/startup.tcl | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 1c89d8c0b..cdec3b0f5 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6852,7 +6852,7 @@ stm32h7x option_write 0 0x20 0x8000000 0x8000000 @end deffn @deffn {Flash Driver} stm32lx -All members of the STM32L microcontroller families from STMicroelectronics +All members of the STM32L0 and STM32L1 microcontroller families from STMicroelectronics include internal flash and use ARM Cortex-M3 and Cortex-M0+ cores. The driver automatically recognizes a number of these chips using the chip identification register, and autoconfigures itself. diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c index e6473f8c2..f112f88f1 100644 --- a/src/flash/nor/stm32lx.c +++ b/src/flash/nor/stm32lx.c @@ -756,7 +756,7 @@ static int stm32lx_probe(struct flash_bank *bank) } if (n == ARRAY_SIZE(stm32lx_parts)) { - LOG_WARNING("Cannot identify target as a STM32L family."); + LOG_ERROR("Cannot identify target as an STM32 L0 or L1 family device."); return ERROR_FAIL; } else { LOG_INFO("Device: %s", stm32lx_info->part_info.device_str); diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl index 63151b50e..725953486 100644 --- a/src/flash/startup.tcl +++ b/src/flash/startup.tcl @@ -109,6 +109,10 @@ proc stm32f3x args { eval stm32f1x $args } proc stm32f4x args { eval stm32f2x $args } proc stm32f7x args { eval stm32f2x $args } +# stm32lx driver supports both STM32 L0 and L1 devices +proc stm32l0x args { eval stm32lx $args } +proc stm32l1x args { eval stm32lx $args } + # stm32wb uses the same flash driver as the stm32l4x proc stm32wbx args { eval stm32l4x $args } From e8c747048fed28edf1900df56e8ffd5ba77b221e Mon Sep 17 00:00:00 2001 From: Piotr Kasprzyk Date: Sat, 8 Dec 2018 18:02:11 +0100 Subject: [PATCH 126/354] Include start-of-region address When $ADDRESS == $BASE that address used to be excluded. After this commit $ADDRESS == $BASE is within the range. Now the rule for "iswithin" is: $BASE <= $ADDRESS < ($BASE + $LEN) Thanks to Antonio Borneo for noticing this. Change-Id: I74373c6010e069372d886fa7ecd8120892616834 Signed-off-by: Piotr Kasprzyk Reviewed-on: http://openocd.zylin.com/4799 Tested-by: jenkins Reviewed-by: Spencer Oliver Reviewed-by: Antonio Borneo --- tcl/memory.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcl/memory.tcl b/tcl/memory.tcl index a7f5b9ac4..3066c1113 100644 --- a/tcl/memory.tcl +++ b/tcl/memory.tcl @@ -58,7 +58,7 @@ set ACCESS_WIDTH_ANY [expr $ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_3 set UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE proc iswithin { ADDRESS BASE LEN } { - return [expr ((($ADDRESS - $BASE) > 0) && (($BASE + $LEN - $ADDRESS) > 0))] + return [expr ((($ADDRESS - $BASE) >= 0) && (($BASE + $LEN - $ADDRESS) > 0))] } proc address_info { ADDRESS } { From 4882acef80d179628e31ee94e931f8fc2ac2698e Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Wed, 22 Jan 2020 08:50:36 +0100 Subject: [PATCH 127/354] jtag_vpi: added an option to stop simulation on exit Command CMD_STOP_SIMU had been defined in jtag_vpi for a long time (since the beginning?) but has not been utilized until now. Its purpose is to signal to the jtag_vpi server (i.e. the RTL simulation software) that the simulation shall be stopped. This commit adds a TCL configuration command that selects whether CMD_STOP_SIMU will be sent to the jtag_vpi server when OpenOCD is about to exit. This functionality is off by default to maintain identical behavior as in previous OpenOCD versions, unless the user enables it explicitly. Change-Id: If3894af6efa61038ccf6c9191f664e2128f2ef11 Signed-off-by: Jan Matyas Reviewed-on: http://openocd.zylin.com/5407 Tested-by: jenkins Reviewed-by: Oleksij Rempel Reviewed-by: Antonio Borneo --- src/jtag/drivers/jtag_vpi.c | 51 +++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c index e5124b5b0..a5a95a5a3 100644 --- a/src/jtag/drivers/jtag_vpi.c +++ b/src/jtag/drivers/jtag_vpi.c @@ -49,11 +49,15 @@ #define CMD_SCAN_CHAIN_FLIP_TMS 3 #define CMD_STOP_SIMU 4 -int server_port = SERVER_PORT; -char *server_address; +/* jtag_vpi server port and address to connect to */ +static int server_port = SERVER_PORT; +static char *server_address; -int sockfd; -struct sockaddr_in serv_addr; +/* Send CMD_STOP_SIMU to server when OpenOCD exits? */ +static bool stop_sim_on_exit; + +static int sockfd; +static struct sockaddr_in serv_addr; /* One jtag_vpi "packet" as sent over a TCP channel. */ struct vpi_cmd { @@ -576,10 +580,28 @@ static int jtag_vpi_init(void) return ERROR_OK; } +static int jtag_vpi_stop_simulation(void) +{ + struct vpi_cmd cmd; + memset(&cmd, 0, sizeof(struct vpi_cmd)); + cmd.length = 0; + cmd.nb_bits = 0; + cmd.cmd = CMD_STOP_SIMU; + return jtag_vpi_send_cmd(&cmd); +} + static int jtag_vpi_quit(void) { + if (stop_sim_on_exit) { + if (jtag_vpi_stop_simulation() != ERROR_OK) + LOG_WARNING("jtag_vpi: failed to send \"stop simulation\" command"); + } + if (close_socket(sockfd) != 0) { + LOG_WARNING("jtag_vpi: could not close jtag_vpi client socket"); + log_socket_error("jtag_vpi"); + } free(server_address); - return close_socket(sockfd); + return ERROR_OK; } COMMAND_HANDLER(jtag_vpi_set_port) @@ -609,6 +631,17 @@ COMMAND_HANDLER(jtag_vpi_set_address) return ERROR_OK; } +COMMAND_HANDLER(jtag_vpi_stop_sim_on_exit_handler) +{ + if (CMD_ARGC != 1) { + LOG_ERROR("jtag_vpi_stop_sim_on_exit expects 1 argument (on|off)"); + return ERROR_COMMAND_SYNTAX_ERROR; + } else { + COMMAND_PARSE_ON_OFF(CMD_ARGV[0], stop_sim_on_exit); + } + return ERROR_OK; +} + static const struct command_registration jtag_vpi_command_handlers[] = { { .name = "jtag_vpi_set_port", @@ -624,6 +657,14 @@ static const struct command_registration jtag_vpi_command_handlers[] = { .help = "set the address of the VPI server", .usage = "ipv4_addr", }, + { + .name = "jtag_vpi_stop_sim_on_exit", + .handler = &jtag_vpi_stop_sim_on_exit_handler, + .mode = COMMAND_CONFIG, + .help = "Configure if simulation stop command shall be sent " + "before OpenOCD exits (default: off)", + .usage = "", + }, COMMAND_REGISTRATION_DONE }; From 9cf7dff97481fc8f698cdedb821be0fde7d6c80a Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 6 Feb 2020 11:02:25 +0100 Subject: [PATCH 128/354] flash/nor/stm32lx: Minor code cleanups Change-Id: I6440a4eb1f65a2f8ae2914b38f21a59955e85e0d Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5438 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/stm32lx.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c index f112f88f1..c3f9c7249 100644 --- a/src/flash/nor/stm32lx.c +++ b/src/flash/nor/stm32lx.c @@ -128,7 +128,7 @@ struct stm32lx_part_info { }; struct stm32lx_flash_bank { - int probed; + bool probed; uint32_t idcode; uint32_t user_bank_size; uint32_t flash_base; @@ -297,7 +297,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32lx_flash_bank_command) bank->driver_priv = stm32lx_info; - stm32lx_info->probed = 0; + stm32lx_info->probed = false; stm32lx_info->user_bank_size = bank->size; /* the stm32l erased value is 0x00 */ @@ -308,8 +308,6 @@ FLASH_BANK_COMMAND_HANDLER(stm32lx_flash_bank_command) COMMAND_HANDLER(stm32lx_handle_mass_erase_command) { - int i; - if (CMD_ARGC < 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -321,7 +319,7 @@ COMMAND_HANDLER(stm32lx_handle_mass_erase_command) retval = stm32lx_mass_erase(bank); if (retval == ERROR_OK) { /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) + for (int i = 0; i < bank->num_sectors; i++) bank->sectors[i].is_erased = 1; command_print(CMD, "stm32lx mass erase complete"); @@ -731,14 +729,13 @@ static int stm32lx_probe(struct flash_bank *bank) { struct target *target = bank->target; struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - int i; uint16_t flash_size_in_kb; uint32_t device_id; uint32_t base_address = FLASH_BANK0_ADDRESS; uint32_t second_bank_base; unsigned int n; - stm32lx_info->probed = 0; + stm32lx_info->probed = false; int retval = stm32lx_read_id_code(bank->target, &device_id); if (retval != ERROR_OK) @@ -852,14 +849,14 @@ static int stm32lx_probe(struct flash_bank *bank) return ERROR_FAIL; } - for (i = 0; i < num_sectors; i++) { + for (int i = 0; i < num_sectors; i++) { bank->sectors[i].offset = i * FLASH_SECTOR_SIZE; bank->sectors[i].size = FLASH_SECTOR_SIZE; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = -1; } - stm32lx_info->probed = 1; + stm32lx_info->probed = true; return ERROR_OK; } From b5c883f298ebd7d459e8247531e6ca3b6dda45cd Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 11:40:17 +0200 Subject: [PATCH 129/354] target/nds32: fix type of magic number The macro NDS32_COMMON_MAGIC was cast-ed to int to avoid compile time error for comparison type mismatch while comparing it with the field common_magic. This is incorrect because the macro value is a 32 bit unsigned value; better changing the type of the field common_magic to keep the unsigned value. Issue identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types TYPECAST_INT_CONSTANT -f {} \; Change-Id: Ib5924b6cecdffe70ab5c78d3b30a9c8e4deb7c7b Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5193 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/target/nds32.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/nds32.h b/src/target/nds32.h index 141dbf4cb..3670fd289 100644 --- a/src/target/nds32.h +++ b/src/target/nds32.h @@ -82,7 +82,7 @@ enum nds32_syscall_id { NDS32_SYSCALL_ERRNO = 6001, }; -#define NDS32_COMMON_MAGIC (int)0xADE5ADE5 +#define NDS32_COMMON_MAGIC 0xADE5ADE5U struct nds32_edm { @@ -235,7 +235,7 @@ struct nds32_misc_config { * Represents a generic Andes core. */ struct nds32 { - int common_magic; + uint32_t common_magic; struct reg_cache *core_cache; /** Handle for the debug module. */ From def7318edd6570fb5484d2a4ee19b7ac1fa39f53 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 15:15:54 +0200 Subject: [PATCH 130/354] jtag/startup.tcl: remove trailing whitespaces Change-Id: I1d6f4f47ee6f8985c84ddb2647e029c5f4e6a55a Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5194 Tested-by: jenkins Reviewed-by: Marc Schink --- src/jtag/startup.tcl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index e522e74d6..8fc3ad5ef 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -34,16 +34,16 @@ proc init_reset { mode } { proc power_restore {} { echo "Sensed power restore, running reset init and halting GDB." reset init - + # Halt GDB so user can deal with a detected power restore. # # After GDB is halted, then output is no longer forwarded # to the GDB console. - set targets [target names] + set targets [target names] foreach t $targets { # New event script. $t invoke-event arp_halt_gdb - } + } } add_help_text power_restore "Overridable procedure run when power restore is detected. Runs 'reset init' by default." @@ -65,11 +65,11 @@ proc srst_deasserted {} { # # After GDB is halted, then output is no longer forwarded # to the GDB console. - set targets [target names] + set targets [target names] foreach t $targets { # New event script. $t invoke-event arp_halt_gdb - } + } } add_help_text srst_deasserted "Overridable procedure run when srst deassert is detected. Runs 'reset init' by default." From 8105c46ba5d219345cc554fd958a65f4e26ae9ce Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 11:29:17 +0200 Subject: [PATCH 131/354] coding style: remove unnecessary parentheses Identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types UNNECESSARY_PARENTHESES -f {} \; then fixed manually. Change-Id: Ia2d9a0953d9b89fc87dc1195aa05c7f63c068c48 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5196 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/target/cortex_m.c | 2 +- src/target/stm8.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 7f59401b1..9a1f2b16f 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -919,7 +919,7 @@ static int cortex_m_step(struct target *target, int current, * a normal step, otherwise we have to manually step over the bkpt * instruction - as such simulate a step */ if (bkpt_inst_found == false) { - if ((cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO)) { + if (cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO) { /* Automatic ISR masking mode off: Just step over the next * instruction, with interrupts on or off as appropriate. */ cortex_m_set_maskints_for_step(target); diff --git a/src/target/stm8.c b/src/target/stm8.c index 54a4bce26..6b03bb5a4 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -356,7 +356,7 @@ static int stm8_set_hwbreak(struct target *target, if ((comparator_list[0].type != HWBRK_EXEC) && (comparator_list[1].type != HWBRK_EXEC)) { - if ((comparator_list[0].type != comparator_list[1].type)) { + if (comparator_list[0].type != comparator_list[1].type) { LOG_ERROR("data hw breakpoints must be of same type"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } From 1492a103db6174bd4d6994ea3487c096aef4560d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 12:50:44 +0200 Subject: [PATCH 132/354] coding style: use ARRAY_SIZE() when possible We have the macro ARRAY_SIZE() already available. Use it! Issue identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types ARRAY_SIZE -f {} \; Change-Id: Ic7da9b710edf118eacb08f9e222f34208c580842 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5198 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/ambiqmicro.c | 3 +-- src/flash/nor/numicro.c | 2 +- src/flash/nor/psoc6.c | 2 +- src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/flash/nor/ambiqmicro.c b/src/flash/nor/ambiqmicro.c index b1e3e72a9..b41b15c07 100644 --- a/src/flash/nor/ambiqmicro.c +++ b/src/flash/nor/ambiqmicro.c @@ -253,8 +253,7 @@ static int ambiqmicro_read_part_info(struct flash_bank *bank) } - if (ambiqmicro_info->target_class < - (sizeof(ambiqmicroParts)/sizeof(ambiqmicroParts[0]))) + if (ambiqmicro_info->target_class < ARRAY_SIZE(ambiqmicroParts)) ambiqmicro_info->target_name = ambiqmicroParts[ambiqmicro_info->target_class].partname; else diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c index c62af04bf..9e18136fa 100644 --- a/src/flash/nor/numicro.c +++ b/src/flash/nor/numicro.c @@ -1663,7 +1663,7 @@ static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_ LOG_INFO("Device ID: 0x%08" PRIx32 "", part_id); /* search part numbers */ - for (size_t i = 0; i < sizeof(NuMicroParts)/sizeof(NuMicroParts[0]); i++) { + for (size_t i = 0; i < ARRAY_SIZE(NuMicroParts); i++) { if (part_id == NuMicroParts[i].partid) { *cpu = &NuMicroParts[i]; LOG_INFO("Device Name: %s", (*cpu)->partname); diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c index 386075e2c..3cdfcc424 100644 --- a/src/flash/nor/psoc6.c +++ b/src/flash/nor/psoc6.c @@ -108,7 +108,7 @@ static const struct row_region safe_sflash_regions[] = { {0x16007C00, 0x400}, /* SFLASH: TOC2 */ }; -#define SFLASH_NUM_REGIONS (sizeof(safe_sflash_regions) / sizeof(safe_sflash_regions[0])) +#define SFLASH_NUM_REGIONS ARRAY_SIZE(safe_sflash_regions) static struct working_area *g_stack_area; static struct armv7m_algorithm g_armv7m_info; diff --git a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c index 53a7e989b..678b097c9 100644 --- a/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c +++ b/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c @@ -48,7 +48,7 @@ uint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN]; #define usbtoxxx_get_type_name(type) \ types_name[((type) - VERSALOON_USB_TO_XXX_CMD_START) \ - % (sizeof(types_name) / sizeof(types_name[0]))] + % ARRAY_SIZE(types_name)] static uint8_t type_pre; static uint16_t usbtoxxx_buffer_index; From 54814015148345c01c8878893daed7b429d2793c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 14 Jun 2019 15:59:17 +0200 Subject: [PATCH 133/354] armv8: check the core state to pass the correct arch to gdb Commit 3799eded6761 ("target/aarch64: add support for multi-architecture gdb") passes the constant string "aarch64" as architecture to gdb. This is not working if the core is running in 32 bits mode; gdb reports: Truncated register 8 in remote 'g' packet then closes the connection with OpenOCD. Make the architecture string dependant from the current state of the core. Change-Id: I16e1614ea02ba29bf87f450b3dfe25c83c9a3612 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5234 Tested-by: jenkins Reviewed-by: Muhammad Omair Javaid --- src/target/armv8.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/target/armv8.c b/src/target/armv8.c index e7369372a..88b932073 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -1753,7 +1753,8 @@ const struct command_registration armv8_command_handlers[] = { const char *armv8_get_gdb_arch(struct target *target) { - return "aarch64"; + struct arm *arm = target_to_arm(target); + return arm->core_state == ARM_STATE_AARCH64 ? "aarch64" : "arm"; } int armv8_get_gdb_reg_list(struct target *target, From ee56c502607760deb1b44b4ab06b1cb3a59029fe Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 18 Jul 2019 15:14:34 +0200 Subject: [PATCH 134/354] stlink: add trace support in DAP direct mode Reuse the existing tracing functionality of HLA mode to support tracing in DAP direct mode. Change-Id: I75a01e88ba5d3e45717e4108b99697ac3225db9e Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5409 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/jtag/drivers/stlink_usb.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index dc2fe8c5a..da1d1b564 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -3462,6 +3462,21 @@ static void stlink_dap_op_quit(struct adiv5_dap *dap) LOG_ERROR("Error closing APs"); } +static int stlink_dap_config_trace(bool enabled, + enum tpiu_pin_protocol pin_protocol, uint32_t port_size, + unsigned int *trace_freq, unsigned int traceclkin_freq, + uint16_t *prescaler) +{ + return stlink_config_trace(stlink_dap_handle, enabled, pin_protocol, + port_size, trace_freq, traceclkin_freq, + prescaler); +} + +static int stlink_dap_trace_read(uint8_t *buf, size_t *size) +{ + return stlink_usb_trace_read(stlink_dap_handle, buf, size); +} + /** */ COMMAND_HANDLER(stlink_dap_serial_command) { @@ -3645,6 +3660,8 @@ struct adapter_driver stlink_dap_adapter_driver = { .speed = stlink_dap_speed, .khz = stlink_dap_khz, .speed_div = stlink_dap_speed_div, + .config_trace = stlink_dap_config_trace, + .poll_trace = stlink_dap_trace_read, .dap_jtag_ops = &stlink_dap_ops, .dap_swd_ops = &stlink_dap_ops, From f1f1f3fe1f2c2ba604205e7163d01b3481e4e96b Mon Sep 17 00:00:00 2001 From: Christopher Head Date: Mon, 27 Jan 2020 13:30:04 -0800 Subject: [PATCH 135/354] flash/nor/stm32h7x: fix incorrect array indexing Change-Id: Iec2246df284953d1442dfefdad8e70041690dfe2 Signed-off-by: Christopher Head Reviewed-on: http://openocd.zylin.com/5417 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Andreas Fritiofson --- src/flash/nor/stm32h7x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 008572915..7ce369be3 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -1057,7 +1057,7 @@ COMMAND_HANDLER(stm32x_handle_option_write_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); if (CMD_ARGC > 3) - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], mask); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], mask); return stm32x_modify_option(bank, reg_offset, value, mask); } From a08d7b7093a89ac54e673f0a4da0c2712e375891 Mon Sep 17 00:00:00 2001 From: Christopher Head Date: Mon, 27 Jan 2020 14:48:15 -0800 Subject: [PATCH 136/354] flash/nor/stm32h7x: check OPTCHANGEERR Without this, a failed attempt to change option bytes will silently appear to succeed but without actually changing the option bytes (confusingly, the option bytes will still read back as if they had been changed until a reboot as well!). Change-Id: Id529c6c384a8a16be75f5702310670d99d8fac79 Signed-off-by: Christopher Head Reviewed-on: http://openocd.zylin.com/5418 Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- src/flash/nor/stm32h7x.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 7ce369be3..152a154bd 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -83,6 +83,7 @@ #define OPT_BSY (1 << 0) #define OPT_RDP_POS 8 #define OPT_RDP_MASK (0xff << OPT_RDP_POS) +#define OPT_OPTCHANGEERR (1 << 30) /* FLASH_OPTCCR register bits */ #define OPT_CLR_OPTCHANGEERR (1 << 30) @@ -343,8 +344,8 @@ static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uin /* wait for completion */ int timeout = FLASH_ERASE_TIMEOUT; + uint32_t status; for (;;) { - uint32_t status; retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_CUR, &status); if (retval != ERROR_OK) { LOG_ERROR("stm32x_options_program: failed to read FLASH_OPTSR_CUR"); @@ -361,6 +362,12 @@ static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uin alive_sleep(1); } + /* check for failure */ + if (status & OPT_OPTCHANGEERR) { + LOG_ERROR("error changing option bytes (OPTCHANGEERR=1)"); + retval = ERROR_FLASH_OPERATION_FAILED; + } + flash_options_lock: retval2 = stm32x_lock_option_reg(bank); if (retval2 != ERROR_OK) From 2a60ae7fee192db54240e5929d6434c0eb3e190d Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sun, 19 Jan 2020 16:56:16 +0100 Subject: [PATCH 137/354] flash/nor/stm32f1x: Some small code cleanups Change-Id: I1fc08b96b179a1376af233b713ae50d6ad7867a0 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5404 Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- src/flash/nor/stm32f1x.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index 91fd541f6..ba0d54e79 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -116,7 +116,7 @@ struct stm32x_options { struct stm32x_flash_bank { struct stm32x_options option_bytes; int ppage_size; - int probed; + bool probed; bool has_dual_banks; /* used to access dual flash bank stm32xl */ @@ -145,7 +145,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) stm32x_info = malloc(sizeof(struct stm32x_flash_bank)); bank->driver_priv = stm32x_info; - stm32x_info->probed = 0; + stm32x_info->probed = false; stm32x_info->has_dual_banks = false; stm32x_info->can_load_options = false; stm32x_info->register_base = FLASH_REG_BASE_B0; @@ -368,7 +368,6 @@ static int stm32x_protect_check(struct flash_bank *bank) static int stm32x_erase(struct flash_bank *bank, int first, int last) { struct target *target = bank->target; - int i; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -386,7 +385,7 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last) if (retval != ERROR_OK) return retval; - for (i = first; i <= last; i++) { + for (int i = first; i <= last; i++) { retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_PER); if (retval != ERROR_OK) return retval; @@ -697,7 +696,7 @@ static int stm32x_probe(struct flash_bank *bank) int page_size; uint32_t base_address = 0x08000000; - stm32x_info->probed = 0; + stm32x_info->probed = false; stm32x_info->register_base = FLASH_REG_BASE_B0; stm32x_info->user_data_offset = 10; stm32x_info->option_offset = 0; @@ -886,7 +885,7 @@ static int stm32x_probe(struct flash_bank *bank) if (num_prot_blocks == 32) bank->prot_blocks[31].size = (num_pages - (31 * stm32x_info->ppage_size)) * page_size; - stm32x_info->probed = 1; + stm32x_info->probed = true; return ERROR_OK; } @@ -1474,8 +1473,6 @@ static int stm32x_mass_erase(struct flash_bank *bank) COMMAND_HANDLER(stm32x_handle_mass_erase_command) { - int i; - if (CMD_ARGC < 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -1487,7 +1484,7 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command) retval = stm32x_mass_erase(bank); if (retval == ERROR_OK) { /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) + for (int i = 0; i < bank->num_sectors; i++) bank->sectors[i].is_erased = 1; command_print(CMD, "stm32x mass erase complete"); From a6dacdff58ef36fcdac00c53ec27f19de1fbce0d Mon Sep 17 00:00:00 2001 From: Christopher Head Date: Fri, 3 Jan 2020 14:49:16 -0800 Subject: [PATCH 138/354] flash/stm32h7x: use alignment infrastructure Report the 32-byte alignemnt requirement via the bank structure rather than enforcing it ad-hoc in the write routine. This allows people to do non-32-byte-aligned writes if they want, with the infrastructure fixing up the addresses passed to the low-level driver. Change-Id: I2c4f532f2000435954a900224dbc9f2c30d1cc94 Signed-off-by: Christopher Head Reviewed-on: http://openocd.zylin.com/5388 Reviewed-by: Tarek BOCHKATI Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/stm32h7x.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 152a154bd..bf003684c 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -170,6 +170,9 @@ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) stm32x_info->probed = 0; stm32x_info->user_bank_size = bank->size; + bank->write_start_alignment = FLASH_BLOCK_SIZE; + bank->write_end_alignment = FLASH_BLOCK_SIZE; + return ERROR_OK; } @@ -610,17 +613,17 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, return ERROR_TARGET_NOT_HALTED; } - if (offset % FLASH_BLOCK_SIZE) { - LOG_WARNING("offset 0x%" PRIx32 " breaks required 32-byte alignment", offset); - return ERROR_FLASH_DST_BREAKS_ALIGNMENT; - } + /* should be enforced via bank->write_start_alignment */ + assert(!(offset % FLASH_BLOCK_SIZE)); + + /* should be enforced via bank->write_end_alignment */ + assert(!(count % FLASH_BLOCK_SIZE)); retval = stm32x_unlock_reg(bank); if (retval != ERROR_OK) goto flash_lock; uint32_t blocks_remaining = count / FLASH_BLOCK_SIZE; - uint32_t bytes_remaining = count % FLASH_BLOCK_SIZE; /* multiple words (32-bytes) to be programmed in block */ if (blocks_remaining) { @@ -667,25 +670,6 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, blocks_remaining--; } - if (bytes_remaining) { - retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_PG | FLASH_PSIZE_64); - if (retval != ERROR_OK) - goto flash_lock; - - retval = target_write_buffer(target, address, bytes_remaining, buffer); - if (retval != ERROR_OK) - goto flash_lock; - - /* Force Write buffer of FLASH_BLOCK_SIZE = 32 bytes */ - retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_PG | FLASH_PSIZE_64 | FLASH_FW); - if (retval != ERROR_OK) - goto flash_lock; - - retval = stm32x_wait_flash_op_queue(bank, FLASH_WRITE_TIMEOUT); - if (retval != ERROR_OK) - goto flash_lock; - } - flash_lock: retval2 = stm32x_lock_reg(bank); if (retval2 != ERROR_OK) From 46176304562951ec41b6c257124d88c6707f4c3d Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Sat, 1 Feb 2020 01:53:35 +0200 Subject: [PATCH 139/354] tcl/interface/ftdi: Add imx8mp-evk internal JTAG interface The imx8mp-evk board has a FT4232H chip connected to the chip's JTAG pins. Switching between this on-board interface and the external ARM-10 connector is controlled by an GPIO which is behind an i2c expander connected to the same FTDI chip. Switching can be performed using the NXP bcu tool: https://github.com/NXPmicro/bcu Change-Id: Ic910515f76eaf09ea6d0f755b026fb09cf09ccfc Signed-off-by: Leonard Crestez Reviewed-on: http://openocd.zylin.com/5426 Tested-by: jenkins Reviewed-by: Tomas Vanek --- tcl/interface/ftdi/imx8mp-evk.cfg | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tcl/interface/ftdi/imx8mp-evk.cfg diff --git a/tcl/interface/ftdi/imx8mp-evk.cfg b/tcl/interface/ftdi/imx8mp-evk.cfg new file mode 100644 index 000000000..4e04e8cd7 --- /dev/null +++ b/tcl/interface/ftdi/imx8mp-evk.cfg @@ -0,0 +1,28 @@ +# +# Configuration file for NXP MC-IMX8MP-EVK on-board internal JTAG +# +# Using this interface requires enabling "remote mode" for the board using the +# NXP bcu tool (see https://github.com/NXPmicro/bcu) +# +# bcu set_gpio remote_en 1 -board=imx8mpevk +# +# The REMOTE_EN gpio is accessible through the same FTDI adapter but it's +# behind an I2C GPIO expander. +# + +adapter driver ftdi +ftdi_vid_pid 0x0403 0x6011 +ftdi_channel 0 + +ftdi_layout_init 0x00f8 0x000b + +ftdi_layout_signal RESET_B -data 0x0010 -oe 0x0010 +# Called SYS_nRST in schematics +ftdi_layout_signal nSRST -data 0x0020 -oe 0x0020 +ftdi_layout_signal IO_nRST -data 0x0040 -oe 0x0040 +ftdi_layout_signal ONOFF_B -data 0x0080 -oe 0x0080 + +ftdi_layout_signal GPIO1 -data 0x0100 -oe 0x0100 +ftdi_layout_signal GPIO2 -data 0x0200 -oe 0x0200 +ftdi_layout_signal GPIO3 -data 0x0400 -oe 0x0400 +ftdi_layout_signal GPIO4 -data 0x0800 -oe 0x0800 From da181fc3ecda55e73544c8c4fb86e3e82d2dc0c9 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Sat, 1 Feb 2020 02:02:04 +0200 Subject: [PATCH 140/354] tcl/board: Add imx8mp-evk Board includes an internal adapter (interface/ftdi/imx8mp-evk.cfg) and a standard external ARM-10 connector. Change-Id: Ibb301011665b1edfb95be1213d8100143f6839dd Signed-off-by: Leonard Crestez Reviewed-on: http://openocd.zylin.com/5427 Tested-by: jenkins Reviewed-by: Tomas Vanek --- tcl/board/imx8mp-evk.cfg | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tcl/board/imx8mp-evk.cfg diff --git a/tcl/board/imx8mp-evk.cfg b/tcl/board/imx8mp-evk.cfg new file mode 100644 index 000000000..97a303ac7 --- /dev/null +++ b/tcl/board/imx8mp-evk.cfg @@ -0,0 +1,15 @@ +# +# configuration file for NXP MC-IMX8MP-EVK +# +# Board includes FTDI-based JTAG adapter: interface/ftdi/imx8mp-evk.cfg +# + +transport select jtag +adapter speed 1000 +reset_config srst_only +adapter srst delay 100 + +set CHIPNAME imx8mp +set CHIPCORES 4 + +source [find target/imx8m.cfg] From 61ef89ce4b06f957ac0bd5cdb1c26ab8b64bc097 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sat, 14 Dec 2019 19:37:41 +0100 Subject: [PATCH 141/354] flash/nor/stm32l4x: lock flash after error Also add locking after option write, it was missing at all. Change-Id: I0227c6a74866f0fe8e40aa58616f0b3115ad5af0 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5361 Tested-by: jenkins Reviewed-by: Andreas Bolsch Reviewed-by: Tarek BOCHKATI --- src/flash/nor/stm32l4x.c | 55 +++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index c8055cd9c..e9fb77e03 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -412,34 +412,39 @@ static int stm32l4_unlock_option_reg(struct flash_bank *bank) static int stm32l4_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value, uint32_t mask) { uint32_t optiondata; + int retval, retval2; - int retval = stm32l4_read_flash_reg(bank, reg_offset, &optiondata); + retval = stm32l4_read_flash_reg(bank, reg_offset, &optiondata); if (retval != ERROR_OK) return retval; retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) - return retval; + goto err_lock; retval = stm32l4_unlock_option_reg(bank); if (retval != ERROR_OK) - return retval; + goto err_lock; optiondata = (optiondata & ~mask) | (value & mask); retval = stm32l4_write_flash_reg(bank, reg_offset, optiondata); if (retval != ERROR_OK) - return retval; + goto err_lock; retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_OPTSTRT); if (retval != ERROR_OK) - return retval; + goto err_lock; retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); + +err_lock: + retval2 = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK | FLASH_OPTLOCK); + if (retval != ERROR_OK) return retval; - return retval; + return retval2; } static int stm32l4_protect_check(struct flash_bank *bank) @@ -489,7 +494,7 @@ static int stm32l4_erase(struct flash_bank *bank, int first, int last) { struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; int i; - int retval; + int retval, retval2; assert(first < bank->num_sectors); assert(last < bank->num_sectors); @@ -501,7 +506,7 @@ static int stm32l4_erase(struct flash_bank *bank, int first, int last) retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) - return retval; + goto err_lock; /* Sector Erase @@ -526,20 +531,22 @@ static int stm32l4_erase(struct flash_bank *bank, int first, int last) erase_flags |= i << FLASH_PAGE_SHIFT; retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, erase_flags); if (retval != ERROR_OK) - return retval; + break; retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); if (retval != ERROR_OK) - return retval; + break; bank->sectors[i].is_erased = 1; } - retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); +err_lock: + retval2 = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); + if (retval != ERROR_OK) return retval; - return ERROR_OK; + return retval2; } static int stm32l4_protect(struct flash_bank *bank, int set, int first, int last) @@ -690,10 +697,11 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) - return retval; + goto err_lock; retval = stm32l4_write_block(bank, buffer, offset, count / 8); +err_lock: retval2 = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); if (retval != ERROR_OK) { @@ -924,7 +932,7 @@ static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size) static int stm32l4_mass_erase(struct flash_bank *bank) { - int retval; + int retval, retval2; struct target *target = bank->target; struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; @@ -940,29 +948,30 @@ static int stm32l4_mass_erase(struct flash_bank *bank) retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) - return retval; + goto err_lock; /* mass erase flash memory */ retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT / 10); if (retval != ERROR_OK) - return retval; + goto err_lock; retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, action); if (retval != ERROR_OK) - return retval; + goto err_lock; + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, action | FLASH_STRT); if (retval != ERROR_OK) - return retval; + goto err_lock; retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); + +err_lock: + retval2 = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); + if (retval != ERROR_OK) return retval; - retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); - if (retval != ERROR_OK) - return retval; - - return ERROR_OK; + return retval2; } COMMAND_HANDLER(stm32l4_handle_mass_erase_command) From 1ef468edc50e83261e1ab8a104716cdaa9e84945 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Fri, 7 Feb 2020 18:36:29 +0100 Subject: [PATCH 142/354] flash/nor/tcl.c: add filld command to write double-word with 64-bit value Change-Id: I2eeda7af7d855ed1284083d025994f8fa9531969 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5443 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 5 +++-- src/flash/nor/tcl.c | 26 ++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index cdec3b0f5..de7dceb78 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5074,10 +5074,11 @@ If @option{unlock} is specified, then the flash is unprotected before erase starts. @end deffn -@deffn Command {flash fillw} address word length +@deffn Command {flash filld} address double-word length +@deffnx Command {flash fillw} address word length @deffnx Command {flash fillh} address halfword length @deffnx Command {flash fillb} address byte length -Fills flash memory with the specified @var{word} (32 bits), +Fills flash memory with the specified @var{double-word} (64 bits), @var{word} (32 bits), @var{halfword} (16 bits), or @var{byte} (8-bit) pattern, starting at @var{address} and continuing for @var{length} units (word/halfword/byte). diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index bd313a0b5..3287dd97f 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -476,7 +476,7 @@ COMMAND_HANDLER(handle_flash_write_image_command) COMMAND_HANDLER(handle_flash_fill_command) { target_addr_t address; - uint32_t pattern; + uint64_t pattern; uint32_t count; struct target *target = get_current_target(CMD_CTX); unsigned i; @@ -487,7 +487,7 @@ COMMAND_HANDLER(handle_flash_fill_command) return ERROR_COMMAND_SYNTAX_ERROR; COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address); - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern); + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], pattern); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count); struct flash_bank *bank; @@ -496,6 +496,9 @@ COMMAND_HANDLER(handle_flash_fill_command) return retval; switch (CMD_NAME[4]) { + case 'd': + wordsize = 8; + break; case 'w': wordsize = 4; break; @@ -541,6 +544,10 @@ COMMAND_HANDLER(handle_flash_fill_command) uint8_t *ptr = buffer + padding_at_start; switch (wordsize) { + case 8: + for (i = 0; i < count; i++, ptr += wordsize) + target_buffer_set_u64(target, ptr, pattern); + break; case 4: for (i = 0; i < count; i++, ptr += wordsize) target_buffer_set_u32(target, ptr, pattern); @@ -577,9 +584,12 @@ COMMAND_HANDLER(handle_flash_fill_command) goto done; for (i = 0, ptr = buffer; i < count; i++) { - uint32_t readback = 0; + uint64_t readback = 0; switch (wordsize) { + case 8: + readback = target_buffer_get_u64(target, ptr); + break; case 4: readback = target_buffer_get_u32(target, ptr); break; @@ -593,7 +603,7 @@ COMMAND_HANDLER(handle_flash_fill_command) if (readback != pattern) { LOG_ERROR( "Verification error address " TARGET_ADDR_FMT - ", read back 0x%02" PRIx32 ", expected 0x%02" PRIx32, + ", read back 0x%02" PRIx64 ", expected 0x%02" PRIx64, address + i * wordsize, readback, pattern); retval = ERROR_FAIL; goto done; @@ -1002,6 +1012,14 @@ static const struct command_registration flash_exec_command_handlers[] = { "before erasing.", }, + { + .name = "filld", + .handler = handle_flash_fill_command, + .mode = COMMAND_EXEC, + .usage = "address value n", + .help = "Fill n double-words with 64-bit value, starting at " + "word address. (No autoerase.)", + }, { .name = "fillw", .handler = handle_flash_fill_command, From 35f846fd52e27fabcdea383a6be5056a9213c939 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:41:55 +0100 Subject: [PATCH 143/354] target/adi_v5_swd: fix clang static analyzer warning Change-Id: I24b3e74b62fad469e3150ad97a10a9ab69c2793b Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5374 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tarek BOCHKATI Reviewed-by: Oleksij Rempel --- src/target/adi_v5_swd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index 8d1153733..ee30ff7ba 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -96,7 +96,7 @@ static int swd_run_inner(struct adiv5_dap *dap) static int swd_connect(struct adiv5_dap *dap) { const struct swd_driver *swd = adiv5_dap_swd_driver(dap); - uint32_t dpidr; + uint32_t dpidr = 0xdeadbeef; int status; /* FIXME validate transport config ... is the From 22df29eee8033be5dd9bdf2429701fa2252dd80b Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Wed, 12 Feb 2020 12:14:06 +0100 Subject: [PATCH 144/354] tcl/board: update ST NUCLEO-H745ZI-Q configuration file to use dapdirect this board embeds and STLINK DAP capable firmware Change-Id: I276e9f44ad6cf7d1ff664898bbc884676bdbc967 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5316 Reviewed-by: Tomas Vanek Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/board/st_nucleo_h745zi.cfg | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tcl/board/st_nucleo_h745zi.cfg b/tcl/board/st_nucleo_h745zi.cfg index bb8a396b5..22d36f686 100644 --- a/tcl/board/st_nucleo_h745zi.cfg +++ b/tcl/board/st_nucleo_h745zi.cfg @@ -1,16 +1,14 @@ # This is an ST NUCLEO-H745ZI-Q board with single STM32H745ZITx chip. -source [find interface/stlink.cfg] -transport select hla_swd +source [find interface/stlink-dap.cfg] +transport select dapdirect_swd -# ST-Link HLA interface do not support multi-AP debugging -# then setting DUAL_CORE and USE_CTI has no effect, because -# it will fall back to single core configuration +# STM32H745xx devices are dual core (Cortex-M7 and Cortex-M4) set DUAL_CORE 1 + +# enable CTI for cross halting both cores set USE_CTI 1 source [find target/stm32h7x_dual_bank.cfg] -# when using ST-Link HLA adapter, DBGMCU accesses are done via AP0 -# unfortunately DBGMCU is not accessible when SRST is asserted reset_config srst_only From 608105dff81c5035886d76d8528412139a56c4a7 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Fri, 9 Aug 2019 11:59:24 +0200 Subject: [PATCH 145/354] Support bitbanging on 64-bit ARM CPUs. The configure.ac file restricted this to only 'arm' CPUs, but ${host_cpu} is 'aarch64' (not 'arm') for 64 bit ARM CPUs. Tested on a Raspberry Pi compute module 3. Change-Id: I6cb1d7e7fadc51dbb12419176f1faf0a0cb0b228 Signed-off-by: Mara Bos Reviewed-on: http://openocd.zylin.com/5274 Tested-by: jenkins Reviewed-by: Antonio Borneo --- configure.ac | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index e86d33f88..e87959c04 100644 --- a/configure.ac +++ b/configure.ac @@ -278,15 +278,7 @@ AC_ARG_ENABLE([ioutil], [build_ioutil=$enableval], [build_ioutil=no]) AS_CASE(["${host_cpu}"], - [arm*], [ - AC_ARG_ENABLE([ep93xx], - AS_HELP_STRING([--enable-ep93xx], [Enable building support for EP93xx based SBCs]), - [build_ep93xx=$enableval], [build_ep93xx=no]) - - AC_ARG_ENABLE([at91rm9200], - AS_HELP_STRING([--enable-at91rm9200], [Enable building support for AT91RM9200 based SBCs]), - [build_at91rm9200=$enableval], [build_at91rm9200=no]) - + [arm*|aarch64], [ AC_ARG_ENABLE([bcm2835gpio], AS_HELP_STRING([--enable-bcm2835gpio], [Enable building support for bitbanging on BCM2835 (as found in Raspberry Pi)]), [build_bcm2835gpio=$enableval], [build_bcm2835gpio=no]) @@ -295,12 +287,25 @@ AS_CASE(["${host_cpu}"], [build_imx_gpio=$enableval], [build_imx_gpio=no]) ], [ - build_ep93xx=no - build_at91rm9200=no build_bcm2835gpio=no build_imx_gpio=no ]) +AS_CASE(["${host_cpu}"], + [arm*], [ + AC_ARG_ENABLE([ep93xx], + AS_HELP_STRING([--enable-ep93xx], [Enable building support for EP93xx based SBCs]), + [build_ep93xx=$enableval], [build_ep93xx=no]) + + AC_ARG_ENABLE([at91rm9200], + AS_HELP_STRING([--enable-at91rm9200], [Enable building support for AT91RM9200 based SBCs]), + [build_at91rm9200=$enableval], [build_at91rm9200=no]) + ], + [ + build_ep93xx=no + build_at91rm9200=no +]) + AC_ARG_ENABLE([gw16012], AS_HELP_STRING([--enable-gw16012], [Enable building support for the Gateworks GW16012 JTAG Programmer]), [build_gw16012=$enableval], [build_gw16012=no]) From 98e9d96239af353bca3bad1bf5f4c809e8cc843b Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Mon, 10 Feb 2020 15:39:19 +0100 Subject: [PATCH 146/354] flash/nor/stm32h7x: Minor code cleanups Change-Id: Ia212b1877abeda27f507de29a3aee2b171c1b8c6 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5448 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Christopher Head --- src/flash/nor/stm32h7x.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index bf003684c..d5b5daab2 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -123,7 +123,7 @@ struct stm32h7x_part_info { }; struct stm32h7x_flash_bank { - int probed; + bool probed; uint32_t idcode; uint32_t user_bank_size; uint32_t flash_regs_base; /* Address of flash reg controller */ @@ -167,7 +167,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) stm32x_info = malloc(sizeof(struct stm32h7x_flash_bank)); bank->driver_priv = stm32x_info; - stm32x_info->probed = 0; + stm32x_info->probed = false; stm32x_info->user_bank_size = bank->size; bank->write_start_alignment = FLASH_BLOCK_SIZE; @@ -701,13 +701,12 @@ static int stm32x_probe(struct flash_bank *bank) { struct target *target = bank->target; struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; - int i; uint16_t flash_size_in_kb; uint32_t device_id; uint32_t base_address = FLASH_BANK0_ADDRESS; uint32_t second_bank_base; - stm32x_info->probed = 0; + stm32x_info->probed = false; stm32x_info->part_info = NULL; int retval = stm32x_read_id_code(bank, &stm32x_info->idcode); @@ -803,12 +802,12 @@ static int stm32x_probe(struct flash_bank *bank) /* fixed memory */ setup_sector(bank, 0, num_pages, stm32x_info->part_info->page_size * 1024); - for (i = 0; i < num_pages; i++) { + for (int i = 0; i < num_pages; i++) { bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 0; } - stm32x_info->probed = 1; + stm32x_info->probed = true; return ERROR_OK; } @@ -980,8 +979,6 @@ flash_lock: COMMAND_HANDLER(stm32x_handle_mass_erase_command) { - int i; - if (CMD_ARGC < 1) { command_print(CMD, "stm32h7x mass_erase "); return ERROR_COMMAND_SYNTAX_ERROR; @@ -995,7 +992,7 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command) retval = stm32x_mass_erase(bank); if (retval == ERROR_OK) { /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) + for (int i = 0; i < bank->num_sectors; i++) bank->sectors[i].is_erased = 1; command_print(CMD, "stm32h7x mass erase complete"); From 066aa24e85532b555e1fd34850327e7f7a570bf8 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Mon, 10 Feb 2020 15:37:45 +0100 Subject: [PATCH 147/354] flash/nor/stm32l4x: Minor code cleanups Change-Id: I3053bbe888ac1f0a0593ef51bf9ca564f1cc27ec Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5449 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Antonio Borneo --- src/flash/nor/stm32l4x.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index e9fb77e03..abbb75b46 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -142,7 +142,7 @@ struct stm32l4_part_info { }; struct stm32l4_flash_bank { - int probed; + bool probed; uint32_t idcode; int bank1_sectors; bool dual_bank_mode; @@ -282,7 +282,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command) * Ask the flash infrastructure to ensure required alignment */ bank->write_start_alignment = bank->write_end_alignment = 8; - stm32l4_info->probed = 0; + stm32l4_info->probed = false; return ERROR_OK; } @@ -725,12 +725,11 @@ static int stm32l4_probe(struct flash_bank *bank) struct target *target = bank->target; struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; const struct stm32l4_part_info *part_info; - int i; uint16_t flash_size_in_kb = 0xffff; uint32_t device_id; uint32_t options; - stm32l4_info->probed = 0; + stm32l4_info->probed = false; /* read stm32 device id register */ int retval = stm32l4_read_idcode(bank, &stm32l4_info->idcode); @@ -875,7 +874,7 @@ static int stm32l4_probe(struct flash_bank *bank) return ERROR_FAIL; } - for (i = 0; i < bank->num_sectors; i++) { + for (int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = i * page_size; /* in dual bank configuration, if there is a gap between banks * we fix up the sector offset to consider this gap */ @@ -886,7 +885,7 @@ static int stm32l4_probe(struct flash_bank *bank) bank->sectors[i].is_protected = 1; } - stm32l4_info->probed = 1; + stm32l4_info->probed = true; return ERROR_OK; } @@ -976,8 +975,6 @@ err_lock: COMMAND_HANDLER(stm32l4_handle_mass_erase_command) { - int i; - if (CMD_ARGC < 1) { command_print(CMD, "stm32l4x mass_erase "); return ERROR_COMMAND_SYNTAX_ERROR; @@ -991,7 +988,7 @@ COMMAND_HANDLER(stm32l4_handle_mass_erase_command) retval = stm32l4_mass_erase(bank); if (retval == ERROR_OK) { /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) + for (int i = 0; i < bank->num_sectors; i++) bank->sectors[i].is_erased = 1; command_print(CMD, "stm32l4x mass erase complete"); From beb610555ad826dda874eee0428deeb1c00ac39d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 23 Jan 2020 15:18:33 +0100 Subject: [PATCH 148/354] adi_v5_dapdirect: fix connect under reset Deassert the reset only if connect under reset is not required; otherwise, assert the reset. This fix aligns the behavior of connect under reset in dapdirect with the behavior in jtag and swd. Change-Id: I937ef4320b44e51ef6cb0e349e12348dbfbe4abb Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5415 Tested-by: jenkins --- src/target/adi_v5_dapdirect.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/target/adi_v5_dapdirect.c b/src/target/adi_v5_dapdirect.c index f12015198..c0deee165 100644 --- a/src/target/adi_v5_dapdirect.c +++ b/src/target/adi_v5_dapdirect.c @@ -179,9 +179,18 @@ static int dapdirect_swd_select(struct command_context *ctx) static int dapdirect_init(struct command_context *ctx) { + enum reset_types jtag_reset_config = jtag_get_reset_config(); + LOG_DEBUG("dapdirect_init()"); - adapter_deassert_reset(); + if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { + if (jtag_reset_config & RESET_SRST_NO_GATING) + adapter_assert_reset(); + else + LOG_WARNING("\'srst_nogate\' reset_config option is required"); + } else + adapter_deassert_reset(); + return ERROR_OK; } From 86d8c05eb68866297cbc1ec5f90d3d1634c69a1e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 14 Jun 2019 10:00:06 +0200 Subject: [PATCH 149/354] log: let command "log_output" to set back its default The default log output is stderr. After the command "log_output" has been used to set an output log file, it is possible to return back to stderr only on *NIX hosts specifying a new log output file as "/dev/stderr", but this is not intuitive, not documented and not portable out of *NIX. Make command "log_output" able to set back the default output to stderr when the parameter is either "default" or is missing. While there, add debug message to log the change and make the command return error on incorrect syntax. Change-Id: I8c7c929780f58e2c23936737c8e7274a96734786 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5233 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 6 +++--- src/helper/log.c | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index de7dceb78..d059cfae2 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -7791,9 +7791,9 @@ echo "Downloading kernel -- please wait" @end example @end deffn -@deffn Command log_output [filename] -Redirect logging to @var{filename}; -the initial log output channel is stderr. +@deffn Command log_output [filename | "default"] +Redirect logging to @var{filename} or set it back to default output; +the default log output channel is stderr. @end deffn @deffn Command add_script_search_dir [directory] diff --git a/src/helper/log.c b/src/helper/log.c index 8f48b928b..ae26df5a1 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -220,6 +220,15 @@ COMMAND_HANDLER(handle_debug_level_command) COMMAND_HANDLER(handle_log_output_command) { + if (CMD_ARGC == 0 || (CMD_ARGC == 1 && strcmp(CMD_ARGV[0], "default") == 0)) { + if (log_output != stderr && log_output != NULL) { + /* Close previous log file, if it was open and wasn't stderr. */ + fclose(log_output); + } + log_output = stderr; + LOG_DEBUG("set log_output to default"); + return ERROR_OK; + } if (CMD_ARGC == 1) { FILE *file = fopen(CMD_ARGV[0], "w"); if (file == NULL) { @@ -231,9 +240,11 @@ COMMAND_HANDLER(handle_log_output_command) fclose(log_output); } log_output = file; + LOG_DEBUG("set log_output to \"%s\"", CMD_ARGV[0]); + return ERROR_OK; } - return ERROR_OK; + return ERROR_COMMAND_SYNTAX_ERROR; } static const struct command_registration log_command_handlers[] = { @@ -242,7 +253,7 @@ static const struct command_registration log_command_handlers[] = { .handler = handle_log_output_command, .mode = COMMAND_ANY, .help = "redirect logging to a file (default: stderr)", - .usage = "file_name", + .usage = "[file_name | \"default\"]", }, { .name = "debug_level", From e7306d361b5d503cf27dfb3dc69298ddad495f88 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 5 May 2019 21:26:56 +0200 Subject: [PATCH 150/354] coding style: fix space around pointer's asterisk The script checkpatch available in new Linux kernel offers an experimental feature for automatically fix the code in place. While still experimental, the feature works quite well for simple fixes, like spacing. This patch has been created automatically with the script under review for inclusion in OpenOCD, using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types POINTER_LOCATION --fix-inplace -f {} \; then manually reviewed. OpenOCD coding style does not mention the space around pointer's asterisk, so no check is enforced. This patch only makes the style uniform across the files. The patch only changes amount and position of whitespace, thus the following commands show empty diff git diff -w git log -w -p git log -w --stat Change-Id: Iefb4998e69bebdfe0d1ae65cadfc8d2c4f166d13 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5197 Tested-by: jenkins --- src/flash/nor/dsp5680xx_flash.c | 2 +- src/flash/nor/numicro.c | 4 ++-- src/flash/nor/sim3x.c | 2 +- src/helper/types.h | 24 ++++++++++++------------ src/jtag/drivers/ftdi.c | 2 +- src/jtag/drivers/osbdm.c | 2 +- src/jtag/jtag.h | 4 ++-- src/rtos/embKernel.c | 2 +- src/rtos/mqx.c | 2 +- src/server/gdb_server.c | 2 +- src/target/avrt.c | 2 +- src/target/dsp563xx_once.c | 16 ++++++++-------- src/target/dsp563xx_once.h | 4 ++-- src/target/dsp5680xx.h | 6 +++--- src/target/riscv/riscv-013.c | 2 +- src/target/target.c | 2 +- 16 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/flash/nor/dsp5680xx_flash.c b/src/flash/nor/dsp5680xx_flash.c index 37b60f001..da675856f 100644 --- a/src/flash/nor/dsp5680xx_flash.c +++ b/src/flash/nor/dsp5680xx_flash.c @@ -154,7 +154,7 @@ static int dsp5680xx_flash_protect(struct flash_bank *bank, int set, int first, * * @return */ -static int dsp5680xx_flash_write(struct flash_bank *bank, const uint8_t* buffer, +static int dsp5680xx_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { int retval; diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c index 9e18136fa..c6dbfb851 100644 --- a/src/flash/nor/numicro.c +++ b/src/flash/nor/numicro.c @@ -1216,7 +1216,7 @@ static int numicro_init_isp(struct target *target) return ERROR_OK; } -static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t addr, uint32_t wdata, uint32_t* rdata) +static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t addr, uint32_t wdata, uint32_t *rdata) { uint32_t timeout, status; int retval = ERROR_OK; @@ -1649,7 +1649,7 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer, return ERROR_OK; } -static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_type** cpu) +static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_type **cpu) { uint32_t part_id; int retval = ERROR_OK; diff --git a/src/flash/nor/sim3x.c b/src/flash/nor/sim3x.c index 7ccf56b6e..4e39705fd 100644 --- a/src/flash/nor/sim3x.c +++ b/src/flash/nor/sim3x.c @@ -471,7 +471,7 @@ static int sim3x_write_block(struct flash_bank *bank, const uint8_t *buf, return ret; } -static int sim3x_flash_write(struct flash_bank *bank, const uint8_t * buffer, uint32_t offset, uint32_t count) +static int sim3x_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { int ret; struct target *target; diff --git a/src/helper/types.h b/src/helper/types.h index 5e35c13b7..b6747f8d4 100644 --- a/src/helper/types.h +++ b/src/helper/types.h @@ -126,17 +126,17 @@ static inline uint64_t le_to_h_u64(const uint8_t *buf) (uint64_t)buf[7] << 56); } -static inline uint32_t le_to_h_u32(const uint8_t* buf) +static inline uint32_t le_to_h_u32(const uint8_t *buf) { return (uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24); } -static inline uint32_t le_to_h_u24(const uint8_t* buf) +static inline uint32_t le_to_h_u24(const uint8_t *buf) { return (uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16); } -static inline uint16_t le_to_h_u16(const uint8_t* buf) +static inline uint16_t le_to_h_u16(const uint8_t *buf) { return (uint16_t)((uint16_t)buf[0] | (uint16_t)buf[1] << 8); } @@ -153,17 +153,17 @@ static inline uint64_t be_to_h_u64(const uint8_t *buf) (uint64_t)buf[0] << 56); } -static inline uint32_t be_to_h_u32(const uint8_t* buf) +static inline uint32_t be_to_h_u32(const uint8_t *buf) { return (uint32_t)((uint32_t)buf[3] | (uint32_t)buf[2] << 8 | (uint32_t)buf[1] << 16 | (uint32_t)buf[0] << 24); } -static inline uint32_t be_to_h_u24(const uint8_t* buf) +static inline uint32_t be_to_h_u24(const uint8_t *buf) { return (uint32_t)((uint32_t)buf[2] | (uint32_t)buf[1] << 8 | (uint32_t)buf[0] << 16); } -static inline uint16_t be_to_h_u16(const uint8_t* buf) +static inline uint16_t be_to_h_u16(const uint8_t *buf) { return (uint16_t)((uint16_t)buf[1] | (uint16_t)buf[0] << 8); } @@ -192,7 +192,7 @@ static inline void h_u64_to_be(uint8_t *buf, int64_t val) buf[7] = (uint8_t) (val >> 0); } -static inline void h_u32_to_le(uint8_t* buf, int val) +static inline void h_u32_to_le(uint8_t *buf, int val) { buf[3] = (uint8_t) (val >> 24); buf[2] = (uint8_t) (val >> 16); @@ -200,7 +200,7 @@ static inline void h_u32_to_le(uint8_t* buf, int val) buf[0] = (uint8_t) (val >> 0); } -static inline void h_u32_to_be(uint8_t* buf, int val) +static inline void h_u32_to_be(uint8_t *buf, int val) { buf[0] = (uint8_t) (val >> 24); buf[1] = (uint8_t) (val >> 16); @@ -208,27 +208,27 @@ static inline void h_u32_to_be(uint8_t* buf, int val) buf[3] = (uint8_t) (val >> 0); } -static inline void h_u24_to_le(uint8_t* buf, int val) +static inline void h_u24_to_le(uint8_t *buf, int val) { buf[2] = (uint8_t) (val >> 16); buf[1] = (uint8_t) (val >> 8); buf[0] = (uint8_t) (val >> 0); } -static inline void h_u24_to_be(uint8_t* buf, int val) +static inline void h_u24_to_be(uint8_t *buf, int val) { buf[0] = (uint8_t) (val >> 16); buf[1] = (uint8_t) (val >> 8); buf[2] = (uint8_t) (val >> 0); } -static inline void h_u16_to_le(uint8_t* buf, int val) +static inline void h_u16_to_le(uint8_t *buf, int val) { buf[1] = (uint8_t) (val >> 8); buf[0] = (uint8_t) (val >> 0); } -static inline void h_u16_to_be(uint8_t* buf, int val) +static inline void h_u16_to_be(uint8_t *buf, int val) { buf[0] = (uint8_t) (val >> 8); buf[1] = (uint8_t) (val >> 0); diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 40d076ecf..a9cdbbe1e 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -213,7 +213,7 @@ static int ftdi_set_signal(const struct signal *s, char value) return ERROR_OK; } -static int ftdi_get_signal(const struct signal *s, uint16_t * value_out) +static int ftdi_get_signal(const struct signal *s, uint16_t *value_out) { uint8_t data_low = 0; uint8_t data_high = 0; diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index 9a570b098..3323557b7 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -297,7 +297,7 @@ static int osbdm_swap(struct osbdm *osbdm, void *tms, void *tdi, return ERROR_OK; } -static int osbdm_flush(struct osbdm *osbdm, struct queue* queue) +static int osbdm_flush(struct osbdm *osbdm, struct queue *queue) { uint8_t tms[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)]; uint8_t tdi[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)]; diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index ff1783158..7f033e0e7 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -162,8 +162,8 @@ void jtag_tap_free(struct jtag_tap *tap); struct jtag_tap *jtag_all_taps(void); const char *jtag_tap_name(const struct jtag_tap *tap); -struct jtag_tap *jtag_tap_by_string(const char* dotted_name); -struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp* interp, Jim_Obj *obj); +struct jtag_tap *jtag_tap_by_string(const char *dotted_name); +struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *obj); struct jtag_tap *jtag_tap_by_position(unsigned abs_position); struct jtag_tap *jtag_tap_next_enabled(struct jtag_tap *p); unsigned jtag_tap_count_enabled(void); diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c index 8a307f198..42d2a8cd0 100644 --- a/src/rtos/embKernel.c +++ b/src/rtos/embKernel.c @@ -135,7 +135,7 @@ static int embKernel_create(struct target *target) } static int embKernel_get_tasks_details(struct rtos *rtos, int64_t iterable, const struct embKernel_params *param, - struct thread_detail *details, const char* state_str) + struct thread_detail *details, const char *state_str) { int64_t task = 0; int retval = target_read_buffer(rtos->target, iterable + param->iterable_task_owner_offset, param->pointer_width, diff --git a/src/rtos/mqx.c b/src/rtos/mqx.c index 6646ad4de..f45c15d23 100644 --- a/src/rtos/mqx.c +++ b/src/rtos/mqx.c @@ -106,7 +106,7 @@ static int mqx_valid_address_check( ) { enum mqx_arch arch_type = ((struct mqx_params *)rtos->rtos_specific_params)->target_arch; - const char * targetname = ((struct mqx_params *)rtos->rtos_specific_params)->target_name; + const char *targetname = ((struct mqx_params *)rtos->rtos_specific_params)->target_name; /* Cortex-M address range */ if (arch_type == mqx_arch_cortexm) { diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 9f1cb7b07..0ca4fa4ee 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -2031,7 +2031,7 @@ static int lookup_add_arch_defined_types(char const **arch_defined_types_list[], static int gdb_generate_reg_type_description(struct target *target, char **tdesc, int *pos, int *size, struct reg_data_type *type, - char const **arch_defined_types_list[], int * num_arch_defined_types) + char const **arch_defined_types_list[], int *num_arch_defined_types) { int retval = ERROR_OK; diff --git a/src/target/avrt.c b/src/target/avrt.c index 1e1898c7e..9cb6f2f34 100644 --- a/src/target/avrt.c +++ b/src/target/avrt.c @@ -145,7 +145,7 @@ static int avr_deassert_reset(struct target *target) return ERROR_OK; } -int avr_jtag_senddat(struct jtag_tap *tap, uint32_t* dr_in, uint32_t dr_out, +int avr_jtag_senddat(struct jtag_tap *tap, uint32_t *dr_in, uint32_t dr_out, int len) { return mcu_write_dr_u32(tap, dr_in, dr_out, len, 1); diff --git a/src/target/dsp563xx_once.c b/src/target/dsp563xx_once.c index fe4927ba3..65ef7070b 100644 --- a/src/target/dsp563xx_once.c +++ b/src/target/dsp563xx_once.c @@ -46,7 +46,7 @@ #define JTAG_INSTR_BYPASS 0x0F /** */ -static inline int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8_t * dr_out, int dr_len, int rti) +static inline int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, int dr_len, int rti) { jtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE); @@ -54,13 +54,13 @@ static inline int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8 } /** */ -static inline int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t * dr_in, uint8_t dr_out, int dr_len, int rti) +static inline int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t *dr_in, uint8_t dr_out, int dr_len, int rti) { return dsp563xx_write_dr(tap, dr_in, &dr_out, dr_len, rti); } /** */ -static inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out, int dr_len, int rti) +static inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t *dr_in, uint32_t dr_out, int dr_len, int rti) { return dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) &dr_out, dr_len, rti); } @@ -79,19 +79,19 @@ static inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t } /* IR and DR functions */ -static inline int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t * ir_in, uint8_t * ir_out, int ir_len, int rti) +static inline int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len, int rti) { jtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE); return ERROR_OK; } -static inline int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out, int ir_len, int rti) +static inline int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti) { return dsp563xx_write_ir(tap, ir_in, &ir_out, ir_len, rti); } -static inline int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out) +static inline int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out) { return dsp563xx_write_ir_u8(tap, ir_in, ir_out, tap->ir_length, 1); } @@ -195,7 +195,7 @@ int dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg } /** once read register with register len */ -int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t * data) +int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t *data) { int err; @@ -212,7 +212,7 @@ int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint } /** once read register */ -int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t * data) +int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t *data) { int err; diff --git a/src/target/dsp563xx_once.h b/src/target/dsp563xx_once.h index da7f5e9b8..811c08698 100644 --- a/src/target/dsp563xx_once.h +++ b/src/target/dsp563xx_once.h @@ -76,9 +76,9 @@ int dsp563xx_once_target_status(struct jtag_tap *tap); /** once read registers */ int dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg *regs, int len); /** once read register */ -int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t * data); +int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t *data); /** once read register */ -int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t * data); +int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t *data); /** once write register */ int dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t data); /** single word instruction */ diff --git a/src/target/dsp5680xx.h b/src/target/dsp5680xx.h index 842796bc7..72557cea2 100644 --- a/src/target/dsp5680xx.h +++ b/src/target/dsp5680xx.h @@ -315,7 +315,7 @@ static inline struct dsp5680xx_common *target_to_dsp5680xx(struct target * * @return */ -int dsp5680xx_f_wr(struct target *target, const uint8_t * buffer, uint32_t address, +int dsp5680xx_f_wr(struct target *target, const uint8_t *buffer, uint32_t address, uint32_t count, int is_flash_lock); /** @@ -329,7 +329,7 @@ int dsp5680xx_f_wr(struct target *target, const uint8_t * buffer, uint32_t addre * * @return */ -int dsp5680xx_f_erase_check(struct target *target, uint8_t * erased, +int dsp5680xx_f_erase_check(struct target *target, uint8_t *erased, uint32_t sector); /** @@ -354,7 +354,7 @@ int dsp5680xx_f_erase(struct target *target, int first, int last); * * @return */ -int dsp5680xx_f_protect_check(struct target *target, uint16_t * protected); +int dsp5680xx_f_protect_check(struct target *target, uint16_t *protected); /** * Writes the flash security words with a specific value. The chip's security will be diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 5683e5a3f..1e5c02764 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -66,7 +66,7 @@ static int write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer); static int riscv013_test_sba_config_reg(struct target *target, target_addr_t legal_address, uint32_t num_words, target_addr_t illegal_address, bool run_sbbusyerror_test); -void write_memory_sba_simple(struct target *target, target_addr_t addr, uint32_t* write_data, +void write_memory_sba_simple(struct target *target, target_addr_t addr, uint32_t *write_data, uint32_t write_size, uint32_t sbcs); void read_memory_sba_simple(struct target *target, target_addr_t addr, uint32_t *rd_buf, uint32_t read_size, uint32_t sbcs); diff --git a/src/target/target.c b/src/target/target.c index 936a5da0d..688d31890 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -2281,7 +2281,7 @@ static int target_read_buffer_default(struct target *target, target_addr_t addre return ERROR_OK; } -int target_checksum_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t* crc) +int target_checksum_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t *crc) { uint8_t *buffer; int retval; From 9d5767b6b005e426f77460c42bafce157de74a25 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 12 May 2019 12:26:46 +0200 Subject: [PATCH 151/354] coding style: add newline at end of text files Some text file is missing newline at EOF. Add it. Change-Id: Ieebc790096f40961283c644642e56fde975e957f Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5167 Tested-by: jenkins --- contrib/loaders/flash/at91sam7x/makefile | 2 +- tcl/board/hilscher_nxhx10.cfg | 2 +- tcl/board/iar_str912_sk.cfg | 2 +- tcl/board/twr-vf65gs10_cmsisdap.cfg | 2 +- tcl/interface/imx-native.cfg | 2 +- tcl/interface/openjtag.cfg | 2 +- tcl/target/c100config.tcl | 2 +- testing/examples/AT91R40008Test/makefile | 2 +- testing/examples/LPC2148Test/makefile | 2 +- testing/examples/LPC2148Test/prj/eclipse_ram.gdb | 2 +- testing/examples/LPC2148Test/prj/eclipse_rom.gdb | 2 +- testing/examples/LPC2294Test/makefile | 2 +- testing/examples/LPC2294Test/prj/eclipse_ram.gdb | 2 +- testing/examples/LPC2294Test/prj/eclipse_rom.gdb | 2 +- testing/examples/SAM7S256Test/makefile | 2 +- testing/examples/SAM7S256Test/results/607.html | 2 +- testing/examples/SAM7X256Test/makefile | 2 +- testing/examples/STM32-103/readme.txt | 2 +- testing/examples/STR710JtagSpeed/makefile | 2 +- testing/examples/STR710Test/makefile | 2 +- testing/examples/STR710Test/prj/eclipse_ram.gdb | 2 +- testing/examples/STR710Test/prj/eclipse_rom.gdb | 2 +- testing/examples/STR912Test/makefile | 2 +- testing/results/template.html | 2 +- testing/results/v0.4.0-rc1/AT91FR40162.html | 2 +- testing/results/v0.4.0-rc1/LPC2148.html | 2 +- testing/results/v0.4.0-rc1/SAM7.html | 2 +- testing/results/v0.4.0-rc1/STR710.html | 2 +- testing/results/v0.4.0-rc1/STR912.html | 2 +- testing/testcases.html | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/contrib/loaders/flash/at91sam7x/makefile b/contrib/loaders/flash/at91sam7x/makefile index c3eaf126b..39482976e 100644 --- a/contrib/loaders/flash/at91sam7x/makefile +++ b/contrib/loaders/flash/at91sam7x/makefile @@ -127,4 +127,4 @@ clean: # #-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF *** \ No newline at end of file +# *** EOF *** diff --git a/tcl/board/hilscher_nxhx10.cfg b/tcl/board/hilscher_nxhx10.cfg index 7ff99165a..add424d4e 100644 --- a/tcl/board/hilscher_nxhx10.cfg +++ b/tcl/board/hilscher_nxhx10.cfg @@ -79,4 +79,4 @@ $_TARGETNAME configure -event reset-init { #flash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME init -reset init \ No newline at end of file +reset init diff --git a/tcl/board/iar_str912_sk.cfg b/tcl/board/iar_str912_sk.cfg index ba060a046..54f517b73 100644 --- a/tcl/board/iar_str912_sk.cfg +++ b/tcl/board/iar_str912_sk.cfg @@ -1,3 +1,3 @@ # The IAR str912-sk evaluation kick start board has an str912 -source [find target/str912.cfg] \ No newline at end of file +source [find target/str912.cfg] diff --git a/tcl/board/twr-vf65gs10_cmsisdap.cfg b/tcl/board/twr-vf65gs10_cmsisdap.cfg index e8db75491..ab4548f99 100644 --- a/tcl/board/twr-vf65gs10_cmsisdap.cfg +++ b/tcl/board/twr-vf65gs10_cmsisdap.cfg @@ -12,4 +12,4 @@ transport select swd source [find board/twr-vf65gs10.cfg] # override reset configuration -reset_config srst_only \ No newline at end of file +reset_config srst_only diff --git a/tcl/interface/imx-native.cfg b/tcl/interface/imx-native.cfg index d9bc7eb04..9e1f38d03 100644 --- a/tcl/interface/imx-native.cfg +++ b/tcl/interface/imx-native.cfg @@ -32,4 +32,4 @@ imx_gpio_swd_nums 1 6 # reset_config srst_only srst_push_pull # or if you have both connected, -# reset_config trst_and_srst srst_push_pull \ No newline at end of file +# reset_config trst_and_srst srst_push_pull diff --git a/tcl/interface/openjtag.cfg b/tcl/interface/openjtag.cfg index 7bd532545..9a5827b14 100644 --- a/tcl/interface/openjtag.cfg +++ b/tcl/interface/openjtag.cfg @@ -5,4 +5,4 @@ # adapter driver openjtag -openjtag_device_desc "Open JTAG Project" \ No newline at end of file +openjtag_device_desc "Open JTAG Project" diff --git a/tcl/target/c100config.tcl b/tcl/target/c100config.tcl index 52efa83c2..a72a2fa84 100644 --- a/tcl/target/c100config.tcl +++ b/tcl/target/c100config.tcl @@ -409,4 +409,4 @@ proc flashUBOOT {file} { putsUART0 "done.\n" putsUART0 "Rebooting, please wait!\n" reboot -} \ No newline at end of file +} diff --git a/testing/examples/AT91R40008Test/makefile b/testing/examples/AT91R40008Test/makefile index c57130a7b..24898a329 100644 --- a/testing/examples/AT91R40008Test/makefile +++ b/testing/examples/AT91R40008Test/makefile @@ -134,4 +134,4 @@ clean: # -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF *** \ No newline at end of file +# *** EOF *** diff --git a/testing/examples/LPC2148Test/makefile b/testing/examples/LPC2148Test/makefile index 3a098c33b..53f45f668 100644 --- a/testing/examples/LPC2148Test/makefile +++ b/testing/examples/LPC2148Test/makefile @@ -144,4 +144,4 @@ clean: # -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF *** \ No newline at end of file +# *** EOF *** diff --git a/testing/examples/LPC2148Test/prj/eclipse_ram.gdb b/testing/examples/LPC2148Test/prj/eclipse_ram.gdb index 4f423124d..ea0e21fc3 100644 --- a/testing/examples/LPC2148Test/prj/eclipse_ram.gdb +++ b/testing/examples/LPC2148Test/prj/eclipse_ram.gdb @@ -8,4 +8,4 @@ monitor mww 0xE01FC040 0x0002 monitor mdw 0xE01FC040 load break main -continue \ No newline at end of file +continue diff --git a/testing/examples/LPC2148Test/prj/eclipse_rom.gdb b/testing/examples/LPC2148Test/prj/eclipse_rom.gdb index 86780056d..3d372a059 100644 --- a/testing/examples/LPC2148Test/prj/eclipse_rom.gdb +++ b/testing/examples/LPC2148Test/prj/eclipse_rom.gdb @@ -8,4 +8,4 @@ monitor mww 0xE01FC040 0x0002 monitor mdw 0xE01FC040 load break main -continue \ No newline at end of file +continue diff --git a/testing/examples/LPC2294Test/makefile b/testing/examples/LPC2294Test/makefile index 6af02fbe1..9ac7fe867 100644 --- a/testing/examples/LPC2294Test/makefile +++ b/testing/examples/LPC2294Test/makefile @@ -144,4 +144,4 @@ clean: # -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF *** \ No newline at end of file +# *** EOF *** diff --git a/testing/examples/LPC2294Test/prj/eclipse_ram.gdb b/testing/examples/LPC2294Test/prj/eclipse_ram.gdb index 4f423124d..ea0e21fc3 100644 --- a/testing/examples/LPC2294Test/prj/eclipse_ram.gdb +++ b/testing/examples/LPC2294Test/prj/eclipse_ram.gdb @@ -8,4 +8,4 @@ monitor mww 0xE01FC040 0x0002 monitor mdw 0xE01FC040 load break main -continue \ No newline at end of file +continue diff --git a/testing/examples/LPC2294Test/prj/eclipse_rom.gdb b/testing/examples/LPC2294Test/prj/eclipse_rom.gdb index 86780056d..3d372a059 100644 --- a/testing/examples/LPC2294Test/prj/eclipse_rom.gdb +++ b/testing/examples/LPC2294Test/prj/eclipse_rom.gdb @@ -8,4 +8,4 @@ monitor mww 0xE01FC040 0x0002 monitor mdw 0xE01FC040 load break main -continue \ No newline at end of file +continue diff --git a/testing/examples/SAM7S256Test/makefile b/testing/examples/SAM7S256Test/makefile index 9e1e83f8e..dabe9a3d8 100644 --- a/testing/examples/SAM7S256Test/makefile +++ b/testing/examples/SAM7S256Test/makefile @@ -143,4 +143,4 @@ clean: # -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF *** \ No newline at end of file +# *** EOF *** diff --git a/testing/examples/SAM7S256Test/results/607.html b/testing/examples/SAM7S256Test/results/607.html index 852c0ad67..e097586ee 100644 --- a/testing/examples/SAM7S256Test/results/607.html +++ b/testing/examples/SAM7S256Test/results/607.html @@ -695,4 +695,4 @@ Note: these tests are not designed to test/debug the target, but to test functio - \ No newline at end of file + diff --git a/testing/examples/SAM7X256Test/makefile b/testing/examples/SAM7X256Test/makefile index 4ad44cf0b..4a5a730da 100644 --- a/testing/examples/SAM7X256Test/makefile +++ b/testing/examples/SAM7X256Test/makefile @@ -143,4 +143,4 @@ clean: # -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF *** \ No newline at end of file +# *** EOF *** diff --git a/testing/examples/STM32-103/readme.txt b/testing/examples/STM32-103/readme.txt index 39b080dd6..f41a03df0 100644 --- a/testing/examples/STM32-103/readme.txt +++ b/testing/examples/STM32-103/readme.txt @@ -3,4 +3,4 @@ Olimex STM32-p103 board. main.elf is a file that can be programmed to flash for testing purposes(e.g. test GDB load performance). -http://www.olimex.com/dev/stm32-p103.html \ No newline at end of file +http://www.olimex.com/dev/stm32-p103.html diff --git a/testing/examples/STR710JtagSpeed/makefile b/testing/examples/STR710JtagSpeed/makefile index 816ab233e..72be7159b 100644 --- a/testing/examples/STR710JtagSpeed/makefile +++ b/testing/examples/STR710JtagSpeed/makefile @@ -131,4 +131,4 @@ clean: # -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF *** \ No newline at end of file +# *** EOF *** diff --git a/testing/examples/STR710Test/makefile b/testing/examples/STR710Test/makefile index 1450b73d5..adac2433a 100644 --- a/testing/examples/STR710Test/makefile +++ b/testing/examples/STR710Test/makefile @@ -143,4 +143,4 @@ clean: # -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF *** \ No newline at end of file +# *** EOF *** diff --git a/testing/examples/STR710Test/prj/eclipse_ram.gdb b/testing/examples/STR710Test/prj/eclipse_ram.gdb index 511ed5914..80efec42d 100644 --- a/testing/examples/STR710Test/prj/eclipse_ram.gdb +++ b/testing/examples/STR710Test/prj/eclipse_ram.gdb @@ -8,4 +8,4 @@ monitor mww 0xA0000050 0x01c2 monitor mdw 0xA0000050 load break main -continue \ No newline at end of file +continue diff --git a/testing/examples/STR710Test/prj/eclipse_rom.gdb b/testing/examples/STR710Test/prj/eclipse_rom.gdb index 9e2c37005..d8eaf1e9f 100644 --- a/testing/examples/STR710Test/prj/eclipse_rom.gdb +++ b/testing/examples/STR710Test/prj/eclipse_rom.gdb @@ -8,4 +8,4 @@ monitor mww 0xA0000050 0x01c2 monitor mdw 0xA0000050 load break main -continue \ No newline at end of file +continue diff --git a/testing/examples/STR912Test/makefile b/testing/examples/STR912Test/makefile index ee7685795..6f8309eab 100644 --- a/testing/examples/STR912Test/makefile +++ b/testing/examples/STR912Test/makefile @@ -143,4 +143,4 @@ clean: # -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -# *** EOF *** \ No newline at end of file +# *** EOF *** diff --git a/testing/results/template.html b/testing/results/template.html index 286bf2e3a..ffc9bbf1f 100644 --- a/testing/results/template.html +++ b/testing/results/template.html @@ -15,4 +15,4 @@ - \ No newline at end of file + diff --git a/testing/results/v0.4.0-rc1/AT91FR40162.html b/testing/results/v0.4.0-rc1/AT91FR40162.html index 0baa31e6b..8dcdf487c 100755 --- a/testing/results/v0.4.0-rc1/AT91FR40162.html +++ b/testing/results/v0.4.0-rc1/AT91FR40162.html @@ -853,4 +853,4 @@ Note: these tests are not designed to test/debug the target, but to test functio - \ No newline at end of file + diff --git a/testing/results/v0.4.0-rc1/LPC2148.html b/testing/results/v0.4.0-rc1/LPC2148.html index 425b52484..24d101129 100755 --- a/testing/results/v0.4.0-rc1/LPC2148.html +++ b/testing/results/v0.4.0-rc1/LPC2148.html @@ -930,4 +930,4 @@ Note: these tests are not designed to test/debug the target, but to test functio - \ No newline at end of file + diff --git a/testing/results/v0.4.0-rc1/SAM7.html b/testing/results/v0.4.0-rc1/SAM7.html index a400a476f..9dcabf88c 100755 --- a/testing/results/v0.4.0-rc1/SAM7.html +++ b/testing/results/v0.4.0-rc1/SAM7.html @@ -850,4 +850,4 @@ Note: these tests are not designed to test/debug the target, but to test functio - \ No newline at end of file + diff --git a/testing/results/v0.4.0-rc1/STR710.html b/testing/results/v0.4.0-rc1/STR710.html index 1a18ad0e6..075d549e3 100755 --- a/testing/results/v0.4.0-rc1/STR710.html +++ b/testing/results/v0.4.0-rc1/STR710.html @@ -904,4 +904,4 @@ The current source language is "auto; currently asm".
- \ No newline at end of file + diff --git a/testing/results/v0.4.0-rc1/STR912.html b/testing/results/v0.4.0-rc1/STR912.html index c8df03488..e9be17b98 100755 --- a/testing/results/v0.4.0-rc1/STR912.html +++ b/testing/results/v0.4.0-rc1/STR912.html @@ -1005,4 +1005,4 @@ verified 420 bytes in 0.350000s (1.172 kb/s)
- \ No newline at end of file + diff --git a/testing/testcases.html b/testing/testcases.html index a151e9f68..13b9e7256 100644 --- a/testing/testcases.html +++ b/testing/testcases.html @@ -563,4 +563,4 @@ Note: these tests are not designed to test/debug the target, but to test functio - \ No newline at end of file + From 74634d177b6c9853d6d38144c8783ff10c1b2e9b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 12 May 2019 12:38:18 +0200 Subject: [PATCH 152/354] coding style: tools: remove empty lines at end of text files Empty lines at end of text files are useless. Remove them. Change-Id: Iea4c8425e137d6252fb2e5b62e0b124c73a01cb6 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5168 Tested-by: jenkins --- tools/release/helpers.sh | 1 - tools/release/version.sh | 1 - tools/st7_dtc_as/st7_dtc_as.pl | 1 - 3 files changed, 3 deletions(-) diff --git a/tools/release/helpers.sh b/tools/release/helpers.sh index 47d5782ab..f06df34e9 100644 --- a/tools/release/helpers.sh +++ b/tools/release/helpers.sh @@ -57,4 +57,3 @@ Release: ${PACKAGE_RELEASE} Type: ${RELEASE_TYPE} INFO } - diff --git a/tools/release/version.sh b/tools/release/version.sh index d6c9434b3..a1c92f708 100755 --- a/tools/release/version.sh +++ b/tools/release/version.sh @@ -146,4 +146,3 @@ do_version() { package_info_load do_version "$@" - diff --git a/tools/st7_dtc_as/st7_dtc_as.pl b/tools/st7_dtc_as/st7_dtc_as.pl index 380c61d80..d4c42d7af 100755 --- a/tools/st7_dtc_as/st7_dtc_as.pl +++ b/tools/st7_dtc_as/st7_dtc_as.pl @@ -706,4 +706,3 @@ if($opt{'b'}) { 0; - From 6bac2828b287e1d8d41f0239ffb21f5855b96896 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 12 May 2019 12:51:28 +0200 Subject: [PATCH 153/354] coding style: testing: remove empty lines at end of text files Empty lines at end of text files are useless. Remove them. Change-Id: Id05a7bd944edccaa03ed9eb48599b2e262664cf0 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5169 Tested-by: jenkins --- testing/build.test1/Makefile | 3 --- testing/build.test1/README.TXT | 1 - testing/build.test1/mingw32_help/include/sys/cdefs.h | 1 - testing/build.test2/README.txt | 1 - testing/examples/AT91R40008Test/prj/ethernut3_ram.ld | 1 - testing/examples/AT91R40008Test/src/crt.s | 4 +--- testing/examples/LPC2148Test/prj/lpc2148_ram.ld | 1 - testing/examples/LPC2148Test/prj/lpc2148_rom.ld | 1 - testing/examples/LPC2148Test/src/crt.s | 4 +--- testing/examples/LPC2294Test/prj/lpc2294_ram.ld | 1 - testing/examples/LPC2294Test/prj/lpc2294_rom.ld | 1 - testing/examples/LPC2294Test/src/crt.s | 4 +--- testing/examples/SAM7S256Test/prj/sam7s256_ram.ld | 1 - testing/examples/SAM7S256Test/prj/sam7s256_rom.ld | 1 - testing/examples/SAM7S256Test/src/crt.s | 4 +--- testing/examples/SAM7X256Test/prj/sam7x256_ram.ld | 1 - testing/examples/SAM7X256Test/prj/sam7x256_rom.ld | 1 - testing/examples/SAM7X256Test/src/crt.s | 4 +--- .../examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb | 7 ------- testing/examples/STR710JtagSpeed/prj/str7_ram.ld | 1 - testing/examples/STR710JtagSpeed/src/crt.s | 4 +--- testing/examples/STR710Test/prj/hitex_str7_rom.ld | 1 - testing/examples/STR710Test/prj/str710_program.script | 7 ------- testing/examples/STR710Test/src/crt.s | 1 - testing/examples/STR912Test/prj/eclipse_ram.gdb | 4 ---- testing/examples/STR912Test/prj/eclipse_rom.gdb | 4 ---- testing/examples/STR912Test/prj/str912_program.script | 7 ------- testing/examples/STR912Test/prj/str912_ram.ld | 1 - testing/examples/STR912Test/prj/str912_rom.ld | 1 - testing/examples/ledtest-imx27ads/Makefile | 1 - testing/examples/ledtest-imx27ads/crt0.S | 1 - testing/examples/ledtest-imx27ads/gdbinit-imx27ads | 1 - testing/examples/ledtest-imx27ads/test.c | 2 -- testing/examples/ledtest-imx31pdk/Makefile | 1 - testing/examples/ledtest-imx31pdk/crt0.S | 1 - testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk | 1 - testing/examples/ledtest-imx31pdk/test.c | 2 -- testing/profile_stm32.txt | 1 - testing/tcl_test.tcl | 3 --- 39 files changed, 6 insertions(+), 81 deletions(-) diff --git a/testing/build.test1/Makefile b/testing/build.test1/Makefile index 7271bf2c6..02b752307 100644 --- a/testing/build.test1/Makefile +++ b/testing/build.test1/Makefile @@ -93,6 +93,3 @@ all.download: linux.ftd2xx_installed \ linux.ft22232_libftdi \ linux.ftd2xx_installed.setup - - - diff --git a/testing/build.test1/README.TXT b/testing/build.test1/README.TXT index c8244382a..7f4d401e8 100644 --- a/testing/build.test1/README.TXT +++ b/testing/build.test1/README.TXT @@ -36,4 +36,3 @@ Dec 26,2008 cd ~/work make cygwin.buildtest - diff --git a/testing/build.test1/mingw32_help/include/sys/cdefs.h b/testing/build.test1/mingw32_help/include/sys/cdefs.h index c401ce794..606205a58 100644 --- a/testing/build.test1/mingw32_help/include/sys/cdefs.h +++ b/testing/build.test1/mingw32_help/include/sys/cdefs.h @@ -20,4 +20,3 @@ details. */ #define __P(protos) protos /* full-blown ANSI C */ #define __CONCAT(__x,__y) __x##__y #endif - diff --git a/testing/build.test2/README.txt b/testing/build.test2/README.txt index d71c14b5a..382105ef0 100644 --- a/testing/build.test2/README.txt +++ b/testing/build.test2/README.txt @@ -56,4 +56,3 @@ For example - in cygwin, type this: ======= **END** ======= - diff --git a/testing/examples/AT91R40008Test/prj/ethernut3_ram.ld b/testing/examples/AT91R40008Test/prj/ethernut3_ram.ld index 604e70412..a5ae16eb8 100644 --- a/testing/examples/AT91R40008Test/prj/ethernut3_ram.ld +++ b/testing/examples/AT91R40008Test/prj/ethernut3_ram.ld @@ -137,4 +137,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/AT91R40008Test/src/crt.s b/testing/examples/AT91R40008Test/src/crt.s index 0b7026118..bab4609a2 100644 --- a/testing/examples/AT91R40008Test/src/crt.s +++ b/testing/examples/AT91R40008Test/src/crt.s @@ -167,6 +167,4 @@ FIQHandler: .weak IRQHandler, FIQHandler .ltorg -/*** EOF ***/ - - +/*** EOF ***/ diff --git a/testing/examples/LPC2148Test/prj/lpc2148_ram.ld b/testing/examples/LPC2148Test/prj/lpc2148_ram.ld index b7951342d..3cbb616f3 100644 --- a/testing/examples/LPC2148Test/prj/lpc2148_ram.ld +++ b/testing/examples/LPC2148Test/prj/lpc2148_ram.ld @@ -137,4 +137,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/LPC2148Test/prj/lpc2148_rom.ld b/testing/examples/LPC2148Test/prj/lpc2148_rom.ld index 5844fffce..9cb12e4f6 100644 --- a/testing/examples/LPC2148Test/prj/lpc2148_rom.ld +++ b/testing/examples/LPC2148Test/prj/lpc2148_rom.ld @@ -138,4 +138,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/LPC2148Test/src/crt.s b/testing/examples/LPC2148Test/src/crt.s index 774f6b4ae..6fd1d3059 100644 --- a/testing/examples/LPC2148Test/src/crt.s +++ b/testing/examples/LPC2148Test/src/crt.s @@ -184,6 +184,4 @@ FIQHandler: .weak IRQHandler, FIQHandler .ltorg -/*** EOF ***/ - - +/*** EOF ***/ diff --git a/testing/examples/LPC2294Test/prj/lpc2294_ram.ld b/testing/examples/LPC2294Test/prj/lpc2294_ram.ld index 17eaedd87..bc4b93947 100644 --- a/testing/examples/LPC2294Test/prj/lpc2294_ram.ld +++ b/testing/examples/LPC2294Test/prj/lpc2294_ram.ld @@ -137,4 +137,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/LPC2294Test/prj/lpc2294_rom.ld b/testing/examples/LPC2294Test/prj/lpc2294_rom.ld index 64a28f0c6..ca71c28c1 100644 --- a/testing/examples/LPC2294Test/prj/lpc2294_rom.ld +++ b/testing/examples/LPC2294Test/prj/lpc2294_rom.ld @@ -138,4 +138,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/LPC2294Test/src/crt.s b/testing/examples/LPC2294Test/src/crt.s index ac17dcd5f..8b24cc195 100644 --- a/testing/examples/LPC2294Test/src/crt.s +++ b/testing/examples/LPC2294Test/src/crt.s @@ -184,6 +184,4 @@ FIQHandler: .weak IRQHandler, FIQHandler .ltorg -/*** EOF ***/ - - +/*** EOF ***/ diff --git a/testing/examples/SAM7S256Test/prj/sam7s256_ram.ld b/testing/examples/SAM7S256Test/prj/sam7s256_ram.ld index 1b857c99f..593e17cac 100644 --- a/testing/examples/SAM7S256Test/prj/sam7s256_ram.ld +++ b/testing/examples/SAM7S256Test/prj/sam7s256_ram.ld @@ -129,4 +129,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/SAM7S256Test/prj/sam7s256_rom.ld b/testing/examples/SAM7S256Test/prj/sam7s256_rom.ld index b64854acd..b181023bb 100644 --- a/testing/examples/SAM7S256Test/prj/sam7s256_rom.ld +++ b/testing/examples/SAM7S256Test/prj/sam7s256_rom.ld @@ -130,4 +130,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/SAM7S256Test/src/crt.s b/testing/examples/SAM7S256Test/src/crt.s index 16e5865ea..b0bae0d63 100644 --- a/testing/examples/SAM7S256Test/src/crt.s +++ b/testing/examples/SAM7S256Test/src/crt.s @@ -220,6 +220,4 @@ FIQHandler: .weak IRQHandler, FIQHandler .ltorg -/*** EOF ***/ - - +/*** EOF ***/ diff --git a/testing/examples/SAM7X256Test/prj/sam7x256_ram.ld b/testing/examples/SAM7X256Test/prj/sam7x256_ram.ld index 1b857c99f..593e17cac 100644 --- a/testing/examples/SAM7X256Test/prj/sam7x256_ram.ld +++ b/testing/examples/SAM7X256Test/prj/sam7x256_ram.ld @@ -129,4 +129,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/SAM7X256Test/prj/sam7x256_rom.ld b/testing/examples/SAM7X256Test/prj/sam7x256_rom.ld index b64854acd..b181023bb 100644 --- a/testing/examples/SAM7X256Test/prj/sam7x256_rom.ld +++ b/testing/examples/SAM7X256Test/prj/sam7x256_rom.ld @@ -130,4 +130,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/SAM7X256Test/src/crt.s b/testing/examples/SAM7X256Test/src/crt.s index 16e5865ea..b0bae0d63 100644 --- a/testing/examples/SAM7X256Test/src/crt.s +++ b/testing/examples/SAM7X256Test/src/crt.s @@ -220,6 +220,4 @@ FIQHandler: .weak IRQHandler, FIQHandler .ltorg -/*** EOF ***/ - - +/*** EOF ***/ diff --git a/testing/examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb b/testing/examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb index 92f8e18e5..9c48e3571 100644 --- a/testing/examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb +++ b/testing/examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb @@ -24,10 +24,3 @@ monitor verify_ircapture disable load break main continue - - - - - - - diff --git a/testing/examples/STR710JtagSpeed/prj/str7_ram.ld b/testing/examples/STR710JtagSpeed/prj/str7_ram.ld index d760f2620..ded9ab4b4 100644 --- a/testing/examples/STR710JtagSpeed/prj/str7_ram.ld +++ b/testing/examples/STR710JtagSpeed/prj/str7_ram.ld @@ -137,4 +137,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/testing/examples/STR710JtagSpeed/src/crt.s b/testing/examples/STR710JtagSpeed/src/crt.s index d1c238c7b..c27d18e02 100644 --- a/testing/examples/STR710JtagSpeed/src/crt.s +++ b/testing/examples/STR710JtagSpeed/src/crt.s @@ -258,6 +258,4 @@ FIQHandler: .weak IRQHandler, FIQHandler .ltorg -/*** EOF ***/ - - +/*** EOF ***/ diff --git a/testing/examples/STR710Test/prj/hitex_str7_rom.ld b/testing/examples/STR710Test/prj/hitex_str7_rom.ld index 11ac4b621..329dbe014 100644 --- a/testing/examples/STR710Test/prj/hitex_str7_rom.ld +++ b/testing/examples/STR710Test/prj/hitex_str7_rom.ld @@ -256,4 +256,3 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } } - diff --git a/testing/examples/STR710Test/prj/str710_program.script b/testing/examples/STR710Test/prj/str710_program.script index b268adf09..b1601b847 100644 --- a/testing/examples/STR710Test/prj/str710_program.script +++ b/testing/examples/STR710Test/prj/str710_program.script @@ -1,8 +1 @@ flash protect 0 0 7 off - - - - - - - diff --git a/testing/examples/STR710Test/src/crt.s b/testing/examples/STR710Test/src/crt.s index c9db5f5ea..0e7cd37d8 100644 --- a/testing/examples/STR710Test/src/crt.s +++ b/testing/examples/STR710Test/src/crt.s @@ -296,4 +296,3 @@ FIQHandler: .ltorg /*** EOF ***/ - diff --git a/testing/examples/STR912Test/prj/eclipse_ram.gdb b/testing/examples/STR912Test/prj/eclipse_ram.gdb index 00a62d705..67def3c4f 100644 --- a/testing/examples/STR912Test/prj/eclipse_ram.gdb +++ b/testing/examples/STR912Test/prj/eclipse_ram.gdb @@ -15,7 +15,3 @@ monitor mww 0x54000000 0xf load break main continue - - - - diff --git a/testing/examples/STR912Test/prj/eclipse_rom.gdb b/testing/examples/STR912Test/prj/eclipse_rom.gdb index 58977cfcd..35cbff8e1 100644 --- a/testing/examples/STR912Test/prj/eclipse_rom.gdb +++ b/testing/examples/STR912Test/prj/eclipse_rom.gdb @@ -15,7 +15,3 @@ monitor mww 0x54000000 0xf load break main continue - - - - diff --git a/testing/examples/STR912Test/prj/str912_program.script b/testing/examples/STR912Test/prj/str912_program.script index df0239b9d..45ec8a7a2 100644 --- a/testing/examples/STR912Test/prj/str912_program.script +++ b/testing/examples/STR912Test/prj/str912_program.script @@ -1,9 +1,2 @@ str9x flash_config 0 4 2 0 0x80000 flash protect 0 0 7 off - - - - - - - diff --git a/testing/examples/STR912Test/prj/str912_ram.ld b/testing/examples/STR912Test/prj/str912_ram.ld index 269ada9bf..9b9e731d4 100644 --- a/testing/examples/STR912Test/prj/str912_ram.ld +++ b/testing/examples/STR912Test/prj/str912_ram.ld @@ -215,4 +215,3 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } } - diff --git a/testing/examples/STR912Test/prj/str912_rom.ld b/testing/examples/STR912Test/prj/str912_rom.ld index 804149d21..aace268ca 100644 --- a/testing/examples/STR912Test/prj/str912_rom.ld +++ b/testing/examples/STR912Test/prj/str912_rom.ld @@ -246,4 +246,3 @@ SECTIONS .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } } - diff --git a/testing/examples/ledtest-imx27ads/Makefile b/testing/examples/ledtest-imx27ads/Makefile index 4009c41b2..a1e0ba3ac 100644 --- a/testing/examples/ledtest-imx27ads/Makefile +++ b/testing/examples/ledtest-imx27ads/Makefile @@ -39,4 +39,3 @@ dump_full: clean: -/bin/rm -f *.o *~ test.elf - diff --git a/testing/examples/ledtest-imx27ads/crt0.S b/testing/examples/ledtest-imx27ads/crt0.S index d7498814c..770982b31 100644 --- a/testing/examples/ledtest-imx27ads/crt0.S +++ b/testing/examples/ledtest-imx27ads/crt0.S @@ -44,4 +44,3 @@ _mainCRTStartup: .word __bss_start__ .LC2: .word __bss_end__ - diff --git a/testing/examples/ledtest-imx27ads/gdbinit-imx27ads b/testing/examples/ledtest-imx27ads/gdbinit-imx27ads index 4764bc738..88fc78a3d 100644 --- a/testing/examples/ledtest-imx27ads/gdbinit-imx27ads +++ b/testing/examples/ledtest-imx27ads/gdbinit-imx27ads @@ -33,4 +33,3 @@ b main # Run to the breakpoint. c - diff --git a/testing/examples/ledtest-imx27ads/test.c b/testing/examples/ledtest-imx27ads/test.c index a3dd52234..01dc284da 100644 --- a/testing/examples/ledtest-imx27ads/test.c +++ b/testing/examples/ledtest-imx27ads/test.c @@ -54,5 +54,3 @@ atexit() { while (1); } /* ATEXIT */ - - diff --git a/testing/examples/ledtest-imx31pdk/Makefile b/testing/examples/ledtest-imx31pdk/Makefile index 74e2fc23f..1ca6a8d15 100644 --- a/testing/examples/ledtest-imx31pdk/Makefile +++ b/testing/examples/ledtest-imx31pdk/Makefile @@ -39,4 +39,3 @@ dump_full: clean: -/bin/rm -f *.o *~ test.elf - diff --git a/testing/examples/ledtest-imx31pdk/crt0.S b/testing/examples/ledtest-imx31pdk/crt0.S index d7498814c..770982b31 100644 --- a/testing/examples/ledtest-imx31pdk/crt0.S +++ b/testing/examples/ledtest-imx31pdk/crt0.S @@ -44,4 +44,3 @@ _mainCRTStartup: .word __bss_start__ .LC2: .word __bss_end__ - diff --git a/testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk b/testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk index 304a8d899..8374f5acb 100644 --- a/testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk +++ b/testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk @@ -33,4 +33,3 @@ b main # Run to the breakpoint. c - diff --git a/testing/examples/ledtest-imx31pdk/test.c b/testing/examples/ledtest-imx31pdk/test.c index 4135f89c0..a7e37b442 100644 --- a/testing/examples/ledtest-imx31pdk/test.c +++ b/testing/examples/ledtest-imx31pdk/test.c @@ -52,5 +52,3 @@ atexit() { while (1); } /* ATEXIT */ - - diff --git a/testing/profile_stm32.txt b/testing/profile_stm32.txt index a7e03b08f..e0eb875ad 100644 --- a/testing/profile_stm32.txt +++ b/testing/profile_stm32.txt @@ -49,4 +49,3 @@ step 114 mem 96 erase 1547 flash fill 15564 - diff --git a/testing/tcl_test.tcl b/testing/tcl_test.tcl index 476e1c21a..3883dd965 100644 --- a/testing/tcl_test.tcl +++ b/testing/tcl_test.tcl @@ -60,6 +60,3 @@ puts "Running help on PC using data from OpenOCD" global ocd_helptext set ocd_helptext [get_help_text] puts [pc_help] - - - From 3bfe4926632d458da449f0438db6949c75b7af59 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 12 May 2019 12:52:59 +0200 Subject: [PATCH 154/354] coding style: doc: remove empty lines at end of text files Empty lines at end of text files are useless. Remove them. Change-Id: I30e4d3d03c4ce846aa7bcefa7366f88732275557 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5170 Tested-by: jenkins --- NEWS-0.5.0 | 1 - TODO | 1 - doc/fdl.texi | 1 - 3 files changed, 3 deletions(-) diff --git a/NEWS-0.5.0 b/NEWS-0.5.0 index add6c1e90..90ea35c41 100644 --- a/NEWS-0.5.0 +++ b/NEWS-0.5.0 @@ -71,4 +71,3 @@ 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/TODO b/TODO index a4102eb3b..c73d772e2 100644 --- a/TODO +++ b/TODO @@ -392,4 +392,3 @@ to complete: /** @file This file contains the @ref thelist page. */ - diff --git a/doc/fdl.texi b/doc/fdl.texi index a18c33ea0..33b2a1646 100644 --- a/doc/fdl.texi +++ b/doc/fdl.texi @@ -449,4 +449,3 @@ to permit their use in free software. @c Local Variables: @c ispell-local-pdict: "ispell-dict" @c End: - From 9ee9bdd2f9e69df816d313d23b50a563c0869428 Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Mon, 27 Jan 2020 15:22:27 +0300 Subject: [PATCH 155/354] Introduce ARCv2 architecture related code This patch is an initial bump of ARC-specific code which implements the ARCv2 target(EMSK board) initializing routine and some basic remote connection/load/continue functionality. Changes: 03.12.2019: -Add return value checks. -Using static code analizer next fixes were made: Mem leak in functions: arc_jtag_read_memory,arc_jtag_read_memory, arc_jtag_write_registers, arc_jtag_read_registers, jim_arc_add_reg_type_flags, jim_arc_add_reg_type_struct, arc_build_reg_cache, arc_mem_read. Dead code in "arc_mem_read"; In arc_save_context, arc_restore_context correct arguments in"memset" calls. In "build_bcr_reg_cache", "arc_build_reg_cache" check if list is not empty. 29.12.2019 -Moved code from arc_v2.c to arc.c -Added checks of the result of calloc/malloc calls -Reworked arc_cmd.c: replaced spagetty code with functions -Moved to one style in if statements - to "if(!bla)" -Changed Licence headers 22.01.2020 -Removed unused variables in arc_common -Renamed register operation functions -Introduced arc_deinit_target function -Fixed interrupt handling in halt/resume: * add irq_state field in arc_common * fix irq enable/disable calls ( now STATUS32 register is used) -Switched from buf_set(get)_us32() usage to target_buffer_set(get)_u32() -Made some cleanup 30.01.2020 -Removed redundant arc_register struct, moved target link to arc_reg_desc -Introduced link to BCR reg cache in arc_common for freeing memory. -Now arc_deinit_target frees all arc-related allocated memory. Valgrind shows no memory leaks. -Inroduced arch description in arc.c 01.02.2020 -Remove small memory allocations in arc_init_reg. Instead created reg_value and feature fields in arc_reg_desc. -Add return value for arc_init_reg() func. -Replaced some integer constants(61,62,63) with defines. -Removed redundant conversions in arc_reg_get_field(). -Moved iccm/dccm configuration code from arc_configure() to separate functions. 19.02.2020 -Change sizeof(struct) to sizeof(*ptr) in allocations -Changed if/while(ptr != NULL) to if/while(ptr) -Removed unused variables from struct arc_jtag -Add additional structs to arc_reg_data_type to reduce amount of memory allocations calls and simplifying memory freeing. -Add helper arc_reg_bitfield_t struct which includes reg_data_type_bitfield object and char[] name. Reduces memory allocations calls. -Add limit for reg_type/reg_type_field names(20 symbols). -Add in jim_arc_add_reg_type*() functions additional argnument checks(amount of field/name size). -In jim_arc_add_reg_type*() reduced amount of memory allocations. -Cleanup of jim_arc_add_reg_type*() functions. -For commands update ".usage" fields according docopt. -Cleanup in arc_jtag.c -Renamed functions which require jtag_exeutre_queue() to arc_jtag_enque_*() -Add arc_jtag_enque_register_rw() function, which r/w to jtag ir/dr regs during regiter r/w. 24.02: -Change include guards in arc* files according coding style -Remove _t suffix in struct arc_reg_bitfield_t -Some cleanup Change-Id: I6ab0e82b12e6ddb683c9d13dfb7dd6f49a30cb9f Signed-off-by: Evgeniy Didin Cc: Alexey Brodkin Reviewed-on: http://openocd.zylin.com/5332 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/Makefile.am | 13 +- src/target/arc.c | 1339 ++++++++++++++++++++++++++++++++++++++++ src/target/arc.h | 212 +++++++ src/target/arc_cmd.c | 977 +++++++++++++++++++++++++++++ src/target/arc_cmd.h | 16 + src/target/arc_jtag.c | 542 ++++++++++++++++ src/target/arc_jtag.h | 70 +++ src/target/arc_mem.c | 287 +++++++++ src/target/arc_mem.h | 21 + src/target/target.c | 2 + 10 files changed, 3478 insertions(+), 1 deletion(-) create mode 100644 src/target/arc.c create mode 100644 src/target/arc.h create mode 100644 src/target/arc_cmd.c create mode 100644 src/target/arc_cmd.h create mode 100644 src/target/arc_jtag.c create mode 100644 src/target/arc_jtag.h create mode 100644 src/target/arc_mem.c create mode 100644 src/target/arc_mem.h diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 5a16def55..30d2339bf 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -24,6 +24,7 @@ noinst_LTLIBRARIES += %D%/libtarget.la $(STM8_SRC) \ $(INTEL_IA32_SRC) \ $(ESIRISC_SRC) \ + $(ARC_SRC) \ %D%/avrt.c \ %D%/dsp563xx.c \ %D%/dsp563xx_once.c \ @@ -156,6 +157,12 @@ ESIRISC_SRC = \ %D%/esirisc_jtag.c \ %D%/esirisc_trace.c +ARC_SRC = \ + %D%/arc.c \ + %D%/arc_cmd.c \ + %D%/arc_jtag.c \ + %D%/arc_mem.c + %C%_libtarget_la_SOURCES += \ %D%/algorithm.h \ %D%/arm.h \ @@ -243,7 +250,11 @@ ESIRISC_SRC = \ %D%/esirisc.h \ %D%/esirisc_jtag.h \ %D%/esirisc_regs.h \ - %D%/esirisc_trace.h + %D%/esirisc_trace.h \ + %D%/arc.h \ + %D%/arc_cmd.h \ + %D%/arc_jtag.h \ + %D%/arc_mem.h include %D%/openrisc/Makefile.am include %D%/riscv/Makefile.am diff --git a/src/target/arc.c b/src/target/arc.c new file mode 100644 index 000000000..45ef725dc --- /dev/null +++ b/src/target/arc.c @@ -0,0 +1,1339 @@ +/*************************************************************************** + * Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. * + * Frank Dols * + * Mischa Jonker * + * Anton Kolesov * + * Evgeniy Didin * + * * + * SPDX-License-Identifier: GPL-2.0-or-later * + ***************************************************************************/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arc.h" + + + +/* + * ARC architecture specific details. + * + * ARC has two types of registers: + * 1) core registers(e.g. r0,r1..) [is_core = true] + * 2) Auxiliary registers [is_core = false].. + * + * Auxiliary registers at the same time can be divided into + * read-only BCR(build configuration regs, e.g. isa_config, mpu_build) and + * R/RW non-BCR ("control" register, e.g. pc, status32_t, debug). + * + * The way of accessing to Core and AUX registers differs on Jtag level. + * BCR/non-BCR describes if the register is immutable and that reading + * unexisting register is safe RAZ, rather then an error. + * Note, core registers cannot be BCR. + * + * In arc/cpu/ tcl files all regiters are defined as core, non-BCR aux + * and BCR aux, in "add-reg" command they are passed to three lists + * respectively: core_reg_descriptions, aux_reg_descriptions, + * bcr_reg_descriptions. + * + * Due to the specifics of accessing to BCR/non-BCR registers there are two + * register caches: + * 1) core_and_aux_cache - includes registers described in + * core_reg_descriptions and aux_reg_descriptions lists. + * Used during save/restore context step. + * 2) bcr_cache - includes registers described bcr_reg_descriptions. + * Currently used internally during configure step. + */ + + + +void arc_reg_data_type_add(struct target *target, + struct arc_reg_data_type *data_type) +{ + LOG_DEBUG("Adding %s reg_data_type", data_type->data_type.id); + struct arc_common *arc = target_to_arc(target); + assert(arc); + + list_add_tail(&data_type->list, &arc->reg_data_types); +} + +/** + * Private implementation of register_get_by_name() for ARC that + * doesn't skip not [yet] existing registers. Used in many places + * for iteration through registers and even for marking required registers as + * existing. + */ +struct reg *arc_reg_get_by_name(struct reg_cache *first, + const char *name, bool search_all) +{ + unsigned int i; + struct reg_cache *cache = first; + + while (cache) { + for (i = 0; i < cache->num_regs; i++) { + if (!strcmp(cache->reg_list[i].name, name)) + return &(cache->reg_list[i]); + } + + if (search_all) + cache = cache->next; + else + break; + } + + return NULL; +} + + +/* Initialize arc_common structure, which passes to openocd target instance */ +static int arc_init_arch_info(struct target *target, struct arc_common *arc, + struct jtag_tap *tap) +{ + arc->common_magic = ARC_COMMON_MAGIC; + target->arch_info = arc; + + arc->jtag_info.tap = tap; + + /* The only allowed ir_length is 4 for ARC jtag. */ + if (tap->ir_length != 4) { + LOG_ERROR("ARC jtag instruction length should be equal to 4"); + return ERROR_FAIL; + } + + /* Add standard GDB data types */ + INIT_LIST_HEAD(&arc->reg_data_types); + struct arc_reg_data_type *std_types = calloc(ARRAY_SIZE(standard_gdb_types), + sizeof(*std_types)); + + if (!std_types) { + LOG_ERROR("Unable to allocate memory"); + return ERROR_FAIL; + } + + for (unsigned int i = 0; i < ARRAY_SIZE(standard_gdb_types); i++) { + std_types[i].data_type.type = standard_gdb_types[i].type; + std_types[i].data_type.id = standard_gdb_types[i].id; + arc_reg_data_type_add(target, &(std_types[i])); + } + + /* Fields related to target descriptions */ + INIT_LIST_HEAD(&arc->core_reg_descriptions); + INIT_LIST_HEAD(&arc->aux_reg_descriptions); + INIT_LIST_HEAD(&arc->bcr_reg_descriptions); + arc->num_regs = 0; + arc->num_core_regs = 0; + arc->num_aux_regs = 0; + arc->num_bcr_regs = 0; + arc->last_general_reg = ULONG_MAX; + arc->pc_index_in_cache = ULONG_MAX; + arc->debug_index_in_cache = ULONG_MAX; + + return ERROR_OK; +} + +int arc_reg_add(struct target *target, struct arc_reg_desc *arc_reg, + const char * const type_name, const size_t type_name_len) +{ + assert(target); + assert(arc_reg); + + struct arc_common *arc = target_to_arc(target); + assert(arc); + + /* Find register type */ + { + struct arc_reg_data_type *type; + list_for_each_entry(type, &arc->reg_data_types, list) + if (!strncmp(type->data_type.id, type_name, type_name_len)) { + arc_reg->data_type = &(type->data_type); + break; + } + + if (!arc_reg->data_type) + return ERROR_ARC_REGTYPE_NOT_FOUND; + } + + if (arc_reg->is_core) { + list_add_tail(&arc_reg->list, &arc->core_reg_descriptions); + arc->num_core_regs += 1; + } else if (arc_reg->is_bcr) { + list_add_tail(&arc_reg->list, &arc->bcr_reg_descriptions); + arc->num_bcr_regs += 1; + } else { + list_add_tail(&arc_reg->list, &arc->aux_reg_descriptions); + arc->num_aux_regs += 1; + } + arc->num_regs += 1; + + LOG_DEBUG( + "added register {name=%s, num=0x%x, type=%s%s%s%s}", + arc_reg->name, arc_reg->arch_num, arc_reg->data_type->id, + arc_reg->is_core ? ", core" : "", arc_reg->is_bcr ? ", bcr" : "", + arc_reg->is_general ? ", general" : "" + ); + + return ERROR_OK; +} + +/* Reading core or aux register */ +static int arc_get_register(struct reg *reg) +{ + assert(reg); + + struct arc_reg_desc *desc = reg->arch_info; + struct target *target = desc->target; + struct arc_common *arc = target_to_arc(target); + + uint32_t value; + + if (reg->valid) { + LOG_DEBUG("Get register (cached) gdb_num=%" PRIu32 ", name=%s, value=0x%" PRIx32, + reg->number, desc->name, target_buffer_get_u32(target, reg->value)); + return ERROR_OK; + } + + if (desc->is_core) { + /* Accessing to R61/R62 registers causes Jtag hang */ + if (desc->arch_num == CORE_R61_NUM || desc->arch_num == CORE_R62_NUM) { + LOG_ERROR("It is forbidden to read core registers 61 and 62."); + return ERROR_FAIL; + } + CHECK_RETVAL(arc_jtag_read_core_reg_one(&arc->jtag_info, desc->arch_num, + &value)); + } else { + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, desc->arch_num, + &value)); + } + + target_buffer_set_u32(target, reg->value, value); + + /* If target is unhalted all register reads should be uncached. */ + if (target->state == TARGET_HALTED) + reg->valid = true; + else + reg->valid = false; + + reg->dirty = false; + + LOG_DEBUG("Get register gdb_num=%" PRIu32 ", name=%s, value=0x%" PRIx32, + reg->number , desc->name, value); + + + return ERROR_OK; +} + +/* Writing core or aux register */ +static int arc_set_register(struct reg *reg, uint8_t *buf) +{ + struct arc_reg_desc *desc = reg->arch_info; + struct target *target = desc->target; + uint32_t value = target_buffer_get_u32(target, buf); + /* Unlike "get" function "set" is supported only if target + * is in halt mode. Async writes are not supported yet. */ + if (target->state != TARGET_HALTED) + return ERROR_TARGET_NOT_HALTED; + + /* Accessing to R61/R62 registers causes Jtag hang */ + if (desc->is_core && (desc->arch_num == CORE_R61_NUM || + desc->arch_num == CORE_R62_NUM)) { + LOG_ERROR("It is forbidden to write core registers 61 and 62."); + return ERROR_FAIL; + } + target_buffer_set_u32(target, reg->value, value); + + LOG_DEBUG("Set register gdb_num=%" PRIu32 ", name=%s, value=0x%08" PRIx32, + reg->number, desc->name, value); + + reg->valid = true; + reg->dirty = true; + + return ERROR_OK; +} + +const struct reg_arch_type arc_reg_type = { + .get = arc_get_register, + .set = arc_set_register, +}; + +/* GDB register groups. For now we suport only general and "empty" */ +static const char * const reg_group_general = "general"; +static const char * const reg_group_other = ""; + +/* Common code to initialize `struct reg` for different registers: core, aux, bcr. */ +static int arc_init_reg(struct target *target, struct reg *reg, + struct arc_reg_desc *reg_desc, unsigned long number) +{ + assert(target); + assert(reg); + assert(reg_desc); + + struct arc_common *arc = target_to_arc(target); + + /* Initialize struct reg */ + reg->name = reg_desc->name; + reg->size = 32; /* All register in ARC are 32-bit */ + reg->value = ®_desc->reg_value; + reg->type = &arc_reg_type; + reg->arch_info = reg_desc; + reg->caller_save = true; /* @todo should be configurable. */ + reg->reg_data_type = reg_desc->data_type; + reg->feature = ®_desc->feature; + + reg->feature->name = reg_desc->gdb_xml_feature; + + /* reg->number is used by OpenOCD as value for @regnum. Thus when setting + * value of a register GDB will use it as a number of register in + * P-packet. OpenOCD gdbserver will then use number of register in + * P-packet as an array index in the reg_list returned by + * arc_regs_get_gdb_reg_list. So to ensure that registers are assigned + * correctly it would be required to either sort registers in + * arc_regs_get_gdb_reg_list or to assign numbers sequentially here and + * according to how registers will be sorted in + * arc_regs_get_gdb_reg_list. Second options is much more simpler. */ + reg->number = number; + + if (reg_desc->is_general) { + arc->last_general_reg = reg->number; + reg->group = reg_group_general; + } else { + reg->group = reg_group_other; + } + + return ERROR_OK; +} + +/* Building aux/core reg_cache */ +static int arc_build_reg_cache(struct target *target) +{ + unsigned long i = 0; + struct arc_reg_desc *reg_desc; + /* get pointers to arch-specific information */ + struct arc_common *arc = target_to_arc(target); + const unsigned long num_regs = arc->num_core_regs + arc->num_aux_regs; + struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); + struct reg_cache *cache = calloc(1, sizeof(*cache)); + struct reg *reg_list = calloc(num_regs, sizeof(*reg_list)); + + if (!cache || !reg_list) { + LOG_ERROR("Not enough memory"); + goto fail; + } + + /* Build the process context cache */ + cache->name = "arc registers"; + cache->next = NULL; + cache->reg_list = reg_list; + cache->num_regs = num_regs; + arc->core_and_aux_cache = cache; + (*cache_p) = cache; + + if (list_empty(&arc->core_reg_descriptions)) { + LOG_ERROR("No core registers were defined"); + goto fail; + } + + list_for_each_entry(reg_desc, &arc->core_reg_descriptions, list) { + CHECK_RETVAL(arc_init_reg(target, ®_list[i], reg_desc, i)); + + LOG_DEBUG("reg n=%3li name=%3s group=%s feature=%s", i, + reg_list[i].name, reg_list[i].group, + reg_list[i].feature->name); + + i += 1; + } + + if (list_empty(&arc->aux_reg_descriptions)) { + LOG_ERROR("No aux registers were defined"); + goto fail; + } + + list_for_each_entry(reg_desc, &arc->aux_reg_descriptions, list) { + CHECK_RETVAL(arc_init_reg(target, ®_list[i], reg_desc, i)); + + LOG_DEBUG("reg n=%3li name=%3s group=%s feature=%s", i, + reg_list[i].name, reg_list[i].group, + reg_list[i].feature->name); + + /* PC and DEBUG are essential so we search for them. */ + if (!strcmp("pc", reg_desc->name)) { + if (arc->pc_index_in_cache != ULONG_MAX) { + LOG_ERROR("Double definition of PC in configuration"); + goto fail; + } + arc->pc_index_in_cache = i; + } else if (!strcmp("debug", reg_desc->name)) { + if (arc->debug_index_in_cache != ULONG_MAX) { + LOG_ERROR("Double definition of DEBUG in configuration"); + goto fail; + } + arc->debug_index_in_cache = i; + } + i += 1; + } + + if (arc->pc_index_in_cache == ULONG_MAX + || arc->debug_index_in_cache == ULONG_MAX) { + LOG_ERROR("`pc' and `debug' registers must be present in target description."); + goto fail; + } + + assert(i == (arc->num_core_regs + arc->num_aux_regs)); + + arc->core_aux_cache_built = true; + + return ERROR_OK; + +fail: + free(cache); + free(reg_list); + + return ERROR_FAIL; +} + +/* Build bcr reg_cache. + * This function must be called only after arc_build_reg_cache */ +static int arc_build_bcr_reg_cache(struct target *target) +{ + /* get pointers to arch-specific information */ + struct arc_common *arc = target_to_arc(target); + const unsigned long num_regs = arc->num_bcr_regs; + struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); + struct reg_cache *cache = malloc(sizeof(*cache)); + struct reg *reg_list = calloc(num_regs, sizeof(*reg_list)); + + struct arc_reg_desc *reg_desc; + unsigned long i = 0; + unsigned long gdb_regnum = arc->core_and_aux_cache->num_regs; + + if (!cache || !reg_list) { + LOG_ERROR("Unable to allocate memory"); + goto fail; + } + + /* Build the process context cache */ + cache->name = "arc.bcr"; + cache->next = NULL; + cache->reg_list = reg_list; + cache->num_regs = num_regs; + arc->bcr_cache = cache; + (*cache_p) = cache; + + if (list_empty(&arc->bcr_reg_descriptions)) { + LOG_ERROR("No BCR registers are defined"); + goto fail; + } + + list_for_each_entry(reg_desc, &arc->bcr_reg_descriptions, list) { + CHECK_RETVAL(arc_init_reg(target, ®_list[i], reg_desc, gdb_regnum)); + /* BCRs always semantically, they are just read-as-zero, if there is + * not real register. */ + reg_list[i].exist = true; + + LOG_DEBUG("reg n=%3li name=%3s group=%s feature=%s", i, + reg_list[i].name, reg_list[i].group, + reg_list[i].feature->name); + i += 1; + gdb_regnum += 1; + } + + assert(i == arc->num_bcr_regs); + + arc->bcr_cache_built = true; + + + return ERROR_OK; +fail: + free(cache); + free(reg_list); + + return ERROR_FAIL; +} + + +static int arc_get_gdb_reg_list(struct target *target, struct reg **reg_list[], + int *reg_list_size, enum target_register_class reg_class) +{ + assert(target->reg_cache); + struct arc_common *arc = target_to_arc(target); + + /* get pointers to arch-specific information storage */ + *reg_list_size = arc->num_regs; + *reg_list = calloc(*reg_list_size, sizeof(struct reg *)); + + if (!*reg_list) { + LOG_ERROR("Unable to allocate memory"); + return ERROR_FAIL; + } + + /* OpenOCD gdb_server API seems to be inconsistent here: when it generates + * XML tdesc it filters out !exist registers, however when creating a + * g-packet it doesn't do so. REG_CLASS_ALL is used in first case, and + * REG_CLASS_GENERAL used in the latter one. Due to this we had to filter + * out !exist register for "general", but not for "all". Attempts to filter out + * !exist for "all" as well will cause a failed check in OpenOCD GDB + * server. */ + if (reg_class == REG_CLASS_ALL) { + unsigned long i = 0; + struct reg_cache *reg_cache = target->reg_cache; + while (reg_cache) { + for (unsigned j = 0; j < reg_cache->num_regs; j++, i++) + (*reg_list)[i] = ®_cache->reg_list[j]; + reg_cache = reg_cache->next; + } + assert(i == arc->num_regs); + LOG_DEBUG("REG_CLASS_ALL: number of regs=%i", *reg_list_size); + } else { + unsigned long i = 0; + unsigned long gdb_reg_number = 0; + struct reg_cache *reg_cache = target->reg_cache; + while (reg_cache) { + for (unsigned j = 0; + j < reg_cache->num_regs && gdb_reg_number <= arc->last_general_reg; + j++) { + if (reg_cache->reg_list[j].exist) { + (*reg_list)[i] = ®_cache->reg_list[j]; + i++; + } + gdb_reg_number += 1; + } + reg_cache = reg_cache->next; + } + *reg_list_size = i; + LOG_DEBUG("REG_CLASS_GENERAL: number of regs=%i", *reg_list_size); + } + + return ERROR_OK; +} + +/* Reading field of struct_type register */ +int arc_reg_get_field(struct target *target, const char *reg_name, + const char *field_name, uint32_t *value_ptr) +{ + struct reg_data_type_struct_field *field; + + LOG_DEBUG("getting register field (reg_name=%s, field_name=%s)", reg_name, field_name); + + /* Get register */ + struct reg *reg = arc_reg_get_by_name(target->reg_cache, reg_name, true); + + if (!reg) { + LOG_ERROR("Requested register `%s' doens't exist.", reg_name); + return ERROR_ARC_REGISTER_NOT_FOUND; + } + + if (reg->reg_data_type->type != REG_TYPE_ARCH_DEFINED + || reg->reg_data_type->type_class != REG_TYPE_CLASS_STRUCT) + return ERROR_ARC_REGISTER_IS_NOT_STRUCT; + + /* Get field in a register */ + struct reg_data_type_struct *reg_struct = + reg->reg_data_type->reg_type_struct; + for (field = reg_struct->fields; + field; + field = field->next) { + if (!strcmp(field->name, field_name)) + break; + } + + if (!field) + return ERROR_ARC_REGISTER_FIELD_NOT_FOUND; + + if (!field->use_bitfields) + return ERROR_ARC_FIELD_IS_NOT_BITFIELD; + + if (!reg->valid) + CHECK_RETVAL(reg->type->get(reg)); + + /* First do endiannes-safe read of register value + * then convert it to binary buffer for further + * field extraction */ + + *value_ptr = buf_get_u32(reg->value, field->bitfield->start, + field->bitfield->end - field->bitfield->start + 1); + + return ERROR_OK; +} + +static int arc_get_register_value(struct target *target, const char *reg_name, + uint32_t *value_ptr) +{ + LOG_DEBUG("reg_name=%s", reg_name); + + struct reg *reg = arc_reg_get_by_name(target->reg_cache, reg_name, true); + + if (!reg) + return ERROR_ARC_REGISTER_NOT_FOUND; + + if (!reg->valid) + CHECK_RETVAL(reg->type->get(reg)); + + *value_ptr = target_buffer_get_u32(target, reg->value); + + return ERROR_OK; +} + + +/* Configure DCCM's */ +static int arc_configure_dccm(struct target *target) +{ + struct arc_common *arc = target_to_arc(target); + + uint32_t dccm_build_version, dccm_build_size0, dccm_build_size1; + CHECK_RETVAL(arc_reg_get_field(target, "dccm_build", "version", + &dccm_build_version)); + CHECK_RETVAL(arc_reg_get_field(target, "dccm_build", "size0", + &dccm_build_size0)); + CHECK_RETVAL(arc_reg_get_field(target, "dccm_build", "size1", + &dccm_build_size1)); + /* There is no yet support of configurable number of cycles, + * So there is no difference between v3 and v4 */ + if ((dccm_build_version == 3 || dccm_build_version == 4) && dccm_build_size0 > 0) { + CHECK_RETVAL(arc_get_register_value(target, "aux_dccm", &(arc->dccm_start))); + uint32_t dccm_size = 0x100; + dccm_size <<= dccm_build_size0; + if (dccm_build_size0 == 0xF) + dccm_size <<= dccm_build_size1; + arc->dccm_end = arc->dccm_start + dccm_size; + LOG_DEBUG("DCCM detected start=0x%" PRIx32 " end=0x%" PRIx32, + arc->dccm_start, arc->dccm_end); + + } + return ERROR_OK; +} + + +/* Configure ICCM's */ + +static int arc_configure_iccm(struct target *target) +{ + struct arc_common *arc = target_to_arc(target); + + /* ICCM0 */ + uint32_t iccm_build_version, iccm_build_size00, iccm_build_size01; + uint32_t aux_iccm = 0; + CHECK_RETVAL(arc_reg_get_field(target, "iccm_build", "version", + &iccm_build_version)); + CHECK_RETVAL(arc_reg_get_field(target, "iccm_build", "iccm0_size0", + &iccm_build_size00)); + CHECK_RETVAL(arc_reg_get_field(target, "iccm_build", "iccm0_size1", + &iccm_build_size01)); + if (iccm_build_version == 4 && iccm_build_size00 > 0) { + CHECK_RETVAL(arc_get_register_value(target, "aux_iccm", &aux_iccm)); + uint32_t iccm0_size = 0x100; + iccm0_size <<= iccm_build_size00; + if (iccm_build_size00 == 0xF) + iccm0_size <<= iccm_build_size01; + /* iccm0 start is located in highest 4 bits of aux_iccm */ + arc->iccm0_start = aux_iccm & 0xF0000000; + arc->iccm0_end = arc->iccm0_start + iccm0_size; + LOG_DEBUG("ICCM0 detected start=0x%" PRIx32 " end=0x%" PRIx32, + arc->iccm0_start, arc->iccm0_end); + } + + /* ICCM1 */ + uint32_t iccm_build_size10, iccm_build_size11; + CHECK_RETVAL(arc_reg_get_field(target, "iccm_build", "iccm1_size0", + &iccm_build_size10)); + CHECK_RETVAL(arc_reg_get_field(target, "iccm_build", "iccm1_size1", + &iccm_build_size11)); + if (iccm_build_version == 4 && iccm_build_size10 > 0) { + /* Use value read for ICCM0 */ + if (!aux_iccm) + CHECK_RETVAL(arc_get_register_value(target, "aux_iccm", &aux_iccm)); + uint32_t iccm1_size = 0x100; + iccm1_size <<= iccm_build_size10; + if (iccm_build_size10 == 0xF) + iccm1_size <<= iccm_build_size11; + arc->iccm1_start = aux_iccm & 0x0F000000; + arc->iccm1_end = arc->iccm1_start + iccm1_size; + LOG_DEBUG("ICCM1 detected start=0x%" PRIx32 " end=0x%" PRIx32, + arc->iccm1_start, arc->iccm1_end); + } + return ERROR_OK; +} + +/* Configure some core features, depending on BCRs. */ +static int arc_configure(struct target *target) +{ + LOG_DEBUG("Configuring ARC ICCM and DCCM"); + + /* Configuring DCCM if DCCM_BUILD and AUX_DCCM are known registers. */ + if (arc_reg_get_by_name(target->reg_cache, "dccm_build", true) && + arc_reg_get_by_name(target->reg_cache, "aux_dccm", true)) + CHECK_RETVAL(arc_configure_dccm(target)); + + /* Configuring ICCM if ICCM_BUILD and AUX_ICCM are known registers. */ + if (arc_reg_get_by_name(target->reg_cache, "iccm_build", true) && + arc_reg_get_by_name(target->reg_cache, "aux_iccm", true)) + CHECK_RETVAL(arc_configure_iccm(target)); + + return ERROR_OK; +} + +/* arc_examine is function, which is used for all arc targets*/ +static int arc_examine(struct target *target) +{ + uint32_t status; + struct arc_common *arc = target_to_arc(target); + + CHECK_RETVAL(arc_jtag_startup(&arc->jtag_info)); + + if (!target_was_examined(target)) { + CHECK_RETVAL(arc_jtag_status(&arc->jtag_info, &status)); + if (status & ARC_JTAG_STAT_RU) + target->state = TARGET_RUNNING; + else + target->state = TARGET_HALTED; + + /* Read BCRs and configure optional registers. */ + CHECK_RETVAL(arc_configure(target)); + + target_set_examined(target); + } + + return ERROR_OK; +} + +static int arc_halt(struct target *target) +{ + uint32_t value, irq_state; + struct arc_common *arc = target_to_arc(target); + + LOG_DEBUG("target->state: %s", target_state_name(target)); + + if (target->state == TARGET_HALTED) { + LOG_DEBUG("target was already halted"); + return ERROR_OK; + } + + if (target->state == TARGET_UNKNOWN) + LOG_WARNING("target was in unknown state when halt was requested"); + + if (target->state == TARGET_RESET) { + if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) { + LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); + return ERROR_TARGET_FAILURE; + } else { + target->debug_reason = DBG_REASON_DBGRQ; + } + } + + /* Break (stop) processor. + * Do read-modify-write sequence, or DEBUG.UB will be reset unintentionally. + * We do not use here arc_get/set_core_reg functions here because they imply + * that the processor is already halted. */ + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG, &value)); + value |= SET_CORE_FORCE_HALT; /* set the HALT bit */ + CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG, value)); + alive_sleep(1); + + /* Save current IRQ state */ + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, &irq_state)); + + if (irq_state & AUX_STATUS32_REG_IE_BIT) + arc->irq_state = 1; + else + arc->irq_state = 0; + + /* update state and notify gdb*/ + target->state = TARGET_HALTED; + CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); + + /* some more debug information */ + if (debug_level >= LOG_LVL_DEBUG) { + LOG_DEBUG("core stopped (halted) DEGUB-REG: 0x%08" PRIx32, value); + CHECK_RETVAL(arc_get_register_value(target, "status32", &value)); + LOG_DEBUG("core STATUS32: 0x%08" PRIx32, value); + } + + return ERROR_OK; +} + +/** + * Read registers that are used in GDB g-packet. We don't read them one-by-one, + * but do that in one batch operation to improve speed. Calls to JTAG layer are + * expensive so it is better to make one big call that reads all necessary + * registers, instead of many calls, one for one register. + */ +static int arc_save_context(struct target *target) +{ + int retval = ERROR_OK; + unsigned int i; + struct arc_common *arc = target_to_arc(target); + struct reg *reg_list = arc->core_and_aux_cache->reg_list; + + LOG_DEBUG("Saving aux and core registers values"); + assert(reg_list); + + /* It is assumed that there is at least one AUX register in the list, for + * example PC. */ + const uint32_t core_regs_size = arc->num_core_regs * sizeof(uint32_t); + /* last_general_reg is inclusive number. To get count of registers it is + * required to do +1. */ + const uint32_t regs_to_scan = + MIN(arc->last_general_reg + 1, arc->num_regs); + const uint32_t aux_regs_size = arc->num_aux_regs * sizeof(uint32_t); + uint32_t *core_values = malloc(core_regs_size); + uint32_t *aux_values = malloc(aux_regs_size); + uint32_t *core_addrs = malloc(core_regs_size); + uint32_t *aux_addrs = malloc(aux_regs_size); + unsigned int core_cnt = 0; + unsigned int aux_cnt = 0; + + if (!core_values || !core_addrs || !aux_values || !aux_addrs) { + LOG_ERROR("Unable to allocate memory"); + retval = ERROR_FAIL; + goto exit; + } + + memset(core_values, 0xff, core_regs_size); + memset(core_addrs, 0xff, core_regs_size); + memset(aux_values, 0xff, aux_regs_size); + memset(aux_addrs, 0xff, aux_regs_size); + + for (i = 0; i < MIN(arc->num_core_regs, regs_to_scan); i++) { + struct reg *reg = &(reg_list[i]); + struct arc_reg_desc *arc_reg = reg->arch_info; + if (!reg->valid && reg->exist) { + core_addrs[core_cnt] = arc_reg->arch_num; + core_cnt += 1; + } + } + + for (i = arc->num_core_regs; i < regs_to_scan; i++) { + struct reg *reg = &(reg_list[i]); + struct arc_reg_desc *arc_reg = reg->arch_info; + if (!reg->valid && reg->exist) { + aux_addrs[aux_cnt] = arc_reg->arch_num; + aux_cnt += 1; + } + } + + /* Read data from target. */ + if (core_cnt > 0) { + retval = arc_jtag_read_core_reg(&arc->jtag_info, core_addrs, core_cnt, core_values); + if (ERROR_OK != retval) { + LOG_ERROR("Attempt to read core registers failed."); + retval = ERROR_FAIL; + goto exit; + } + } + if (aux_cnt > 0) { + retval = arc_jtag_read_aux_reg(&arc->jtag_info, aux_addrs, aux_cnt, aux_values); + if (ERROR_OK != retval) { + LOG_ERROR("Attempt to read aux registers failed."); + retval = ERROR_FAIL; + goto exit; + } + } + + /* Parse core regs */ + core_cnt = 0; + for (i = 0; i < MIN(arc->num_core_regs, regs_to_scan); i++) { + struct reg *reg = &(reg_list[i]); + struct arc_reg_desc *arc_reg = reg->arch_info; + if (!reg->valid && reg->exist) { + target_buffer_set_u32(target, reg->value, core_values[core_cnt]); + core_cnt += 1; + reg->valid = true; + reg->dirty = false; + LOG_DEBUG("Get core register regnum=%" PRIu32 ", name=%s, value=0x%08" PRIx32, + i, arc_reg->name, core_values[core_cnt]); + } + } + + /* Parse aux regs */ + aux_cnt = 0; + for (i = arc->num_core_regs; i < regs_to_scan; i++) { + struct reg *reg = &(reg_list[i]); + struct arc_reg_desc *arc_reg = reg->arch_info; + if (!reg->valid && reg->exist) { + target_buffer_set_u32(target, reg->value, aux_values[aux_cnt]); + aux_cnt += 1; + reg->valid = true; + reg->dirty = false; + LOG_DEBUG("Get aux register regnum=%" PRIu32 ", name=%s, value=0x%08" PRIx32, + i , arc_reg->name, aux_values[aux_cnt]); + } + } + +exit: + free(core_values); + free(core_addrs); + free(aux_values); + free(aux_addrs); + + return retval; +} + +static int arc_examine_debug_reason(struct target *target) +{ + uint32_t debug_bh; + + /* Only check for reason if don't know it already. */ + /* BTW After singlestep at this point core is not marked as halted, so + * reading from memory to get current instruction wouldn't work anyway. */ + if (target->debug_reason == DBG_REASON_DBGRQ || + target->debug_reason == DBG_REASON_SINGLESTEP) { + return ERROR_OK; + } + + CHECK_RETVAL(arc_reg_get_field(target, "debug", "bh", + &debug_bh)); + + if (debug_bh) { + /* DEBUG.BH is set if core halted due to BRK instruction. */ + target->debug_reason = DBG_REASON_BREAKPOINT; + } else { + /* TODO: Add Actionpoint check when AP support will be introduced*/ + LOG_WARNING("Unknown debug reason"); + } + + return ERROR_OK; +} + +static int arc_debug_entry(struct target *target) +{ + CHECK_RETVAL(arc_save_context(target)); + + /* TODO: reset internal indicators of caches states, otherwise D$/I$ + * will not be flushed/invalidated when required. */ + CHECK_RETVAL(arc_examine_debug_reason(target)); + + return ERROR_OK; +} + +static int arc_poll(struct target *target) +{ + uint32_t status, value; + struct arc_common *arc = target_to_arc(target); + + /* gdb calls continuously through this arc_poll() function */ + CHECK_RETVAL(arc_jtag_status(&arc->jtag_info, &status)); + + /* check for processor halted */ + if (status & ARC_JTAG_STAT_RU) { + if (target->state != TARGET_RUNNING) { + LOG_WARNING("target is still running!"); + target->state = TARGET_RUNNING; + } + return ERROR_OK; + } + /* In some cases JTAG status register indicates that + * processor is in halt mode, but processor is still running. + * We check halt bit of AUX STATUS32 register for setting correct state. */ + if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { + CHECK_RETVAL(arc_get_register_value(target, "status32", &value)); + if (value & AUX_STATUS32_REG_HALT_BIT) { + LOG_DEBUG("ARC core in halt or reset state."); + target->state = TARGET_HALTED; + CHECK_RETVAL(arc_debug_entry(target)); + CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); + } else { + LOG_DEBUG("Discrepancy of STATUS32[0] HALT bit and ARC_JTAG_STAT_RU, " + "target is still running"); + } + + } else if (target->state == TARGET_DEBUG_RUNNING) { + + target->state = TARGET_HALTED; + LOG_DEBUG("ARC core is in debug running mode"); + + CHECK_RETVAL(arc_debug_entry(target)); + + CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED)); + } + + return ERROR_OK; +} + +static int arc_assert_reset(struct target *target) +{ + struct arc_common *arc = target_to_arc(target); + enum reset_types jtag_reset_config = jtag_get_reset_config(); + bool srst_asserted = false; + + LOG_DEBUG("target->state: %s", target_state_name(target)); + + if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) { + /* allow scripts to override the reset event */ + + target_handle_event(target, TARGET_EVENT_RESET_ASSERT); + register_cache_invalidate(arc->core_and_aux_cache); + /* An ARC target might be in halt state after reset, so + * if script requested processor to resume, then it must + * be manually started to ensure that this request + * is satisfied. */ + if (target->state == TARGET_HALTED && !target->reset_halt) { + /* Resume the target and continue from the current + * PC register value. */ + LOG_DEBUG("Starting CPU execution after reset"); + CHECK_RETVAL(target_resume(target, 1, 0, 0, 0)); + } + target->state = TARGET_RESET; + + return ERROR_OK; + } + + /* some cores support connecting while srst is asserted + * use that mode if it has been configured */ + if (!(jtag_reset_config & RESET_SRST_PULLS_TRST) && + (jtag_reset_config & RESET_SRST_NO_GATING)) { + jtag_add_reset(0, 1); + srst_asserted = true; + } + + if (jtag_reset_config & RESET_HAS_SRST) { + /* should issue a srst only, but we may have to assert trst as well */ + if (jtag_reset_config & RESET_SRST_PULLS_TRST) + jtag_add_reset(1, 1); + else if (!srst_asserted) + jtag_add_reset(0, 1); + } + + target->state = TARGET_RESET; + jtag_add_sleep(50000); + + register_cache_invalidate(arc->core_and_aux_cache); + + if (target->reset_halt) + CHECK_RETVAL(target_halt(target)); + + return ERROR_OK; +} + +static int arc_deassert_reset(struct target *target) +{ + LOG_DEBUG("target->state: %s", target_state_name(target)); + + /* deassert reset lines */ + jtag_add_reset(0, 0); + + return ERROR_OK; +} + +static int arc_arch_state(struct target *target) +{ + uint32_t pc_value; + + if (debug_level < LOG_LVL_DEBUG) + return ERROR_OK; + + CHECK_RETVAL(arc_get_register_value(target, "pc", &pc_value)); + + LOG_DEBUG("target state: %s; PC at: 0x%08" PRIx32, + target_state_name(target), + pc_value); + + return ERROR_OK; +} + +/** + * See arc_save_context() for reason why we want to dump all regs at once. + * This however means that if there are dependencies between registers they + * will not be observable until target will be resumed. + */ +static int arc_restore_context(struct target *target) +{ + int retval = ERROR_OK; + unsigned int i; + struct arc_common *arc = target_to_arc(target); + struct reg *reg_list = arc->core_and_aux_cache->reg_list; + + LOG_DEBUG("Restoring registers values"); + assert(reg_list); + + const uint32_t core_regs_size = arc->num_core_regs * sizeof(uint32_t); + const uint32_t aux_regs_size = arc->num_aux_regs * sizeof(uint32_t); + uint32_t *core_values = malloc(core_regs_size); + uint32_t *aux_values = malloc(aux_regs_size); + uint32_t *core_addrs = malloc(core_regs_size); + uint32_t *aux_addrs = malloc(aux_regs_size); + unsigned int core_cnt = 0; + unsigned int aux_cnt = 0; + + if (!core_values || !core_addrs || !aux_values || !aux_addrs) { + LOG_ERROR("Unable to allocate memory"); + retval = ERROR_FAIL; + goto exit; + } + + memset(core_values, 0xff, core_regs_size); + memset(core_addrs, 0xff, core_regs_size); + memset(aux_values, 0xff, aux_regs_size); + memset(aux_addrs, 0xff, aux_regs_size); + + for (i = 0; i < arc->num_core_regs; i++) { + struct reg *reg = &(reg_list[i]); + struct arc_reg_desc *arc_reg = reg->arch_info; + if (reg->valid && reg->exist && reg->dirty) { + LOG_DEBUG("Will write regnum=%u", i); + core_addrs[core_cnt] = arc_reg->arch_num; + core_values[core_cnt] = target_buffer_get_u32(target, reg->value); + core_cnt += 1; + } + } + + for (i = 0; i < arc->num_aux_regs; i++) { + struct reg *reg = &(reg_list[arc->num_core_regs + i]); + struct arc_reg_desc *arc_reg = reg->arch_info; + if (reg->valid && reg->exist && reg->dirty) { + LOG_DEBUG("Will write regnum=%lu", arc->num_core_regs + i); + aux_addrs[aux_cnt] = arc_reg->arch_num; + aux_values[aux_cnt] = target_buffer_get_u32(target, reg->value); + aux_cnt += 1; + } + } + + /* Write data to target. + * Check before write, if aux and core count is greater than 0. */ + if (core_cnt > 0) { + retval = arc_jtag_write_core_reg(&arc->jtag_info, core_addrs, core_cnt, core_values); + if (ERROR_OK != retval) { + LOG_ERROR("Attempt to write to core registers failed."); + retval = ERROR_FAIL; + goto exit; + } + } + + if (aux_cnt > 0) { + retval = arc_jtag_write_aux_reg(&arc->jtag_info, aux_addrs, aux_cnt, aux_values); + if (ERROR_OK != retval) { + LOG_ERROR("Attempt to write to aux registers failed."); + retval = ERROR_FAIL; + goto exit; + } + } + +exit: + free(core_values); + free(core_addrs); + free(aux_values); + free(aux_addrs); + + return retval; +} + +static int arc_enable_interrupts(struct target *target, int enable) +{ + uint32_t value; + + struct arc_common *arc = target_to_arc(target); + + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, &value)); + + if (enable) { + /* enable interrupts */ + value |= SET_CORE_ENABLE_INTERRUPTS; + CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, value)); + LOG_DEBUG("interrupts enabled"); + } else { + /* disable interrupts */ + value &= ~SET_CORE_ENABLE_INTERRUPTS; + CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, value)); + LOG_DEBUG("interrupts disabled"); + } + + return ERROR_OK; +} + +static int arc_resume(struct target *target, int current, target_addr_t address, + int handle_breakpoints, int debug_execution) +{ + struct arc_common *arc = target_to_arc(target); + uint32_t resume_pc = 0; + uint32_t value; + struct reg *pc = &arc->core_and_aux_cache->reg_list[arc->pc_index_in_cache]; + + LOG_DEBUG("current:%i, address:0x%08" TARGET_PRIxADDR ", handle_breakpoints(not supported yet):%i," + " debug_execution:%i", current, address, handle_breakpoints, debug_execution); + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* current = 1: continue on current PC, otherwise continue at
*/ + if (!current) { + target_buffer_set_u32(target, pc->value, address); + pc->dirty = 1; + pc->valid = 1; + LOG_DEBUG("Changing the value of current PC to 0x%08" TARGET_PRIxADDR, address); + } + + if (!current) + resume_pc = address; + else + resume_pc = target_buffer_get_u32(target, pc->value); + + CHECK_RETVAL(arc_restore_context(target)); + + LOG_DEBUG("Target resumes from PC=0x%" PRIx32 ", pc.dirty=%i, pc.valid=%i", + resume_pc, pc->dirty, pc->valid); + + /* check if GDB tells to set our PC where to continue from */ + if ((pc->valid == 1) && (resume_pc == target_buffer_get_u32(target, pc->value))) { + value = target_buffer_get_u32(target, pc->value); + LOG_DEBUG("resume Core (when start-core) with PC @:0x%08" PRIx32, value); + CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_PC_REG, value)); + } + + /* Restore IRQ state if not in debug_execution*/ + if (!debug_execution) + CHECK_RETVAL(arc_enable_interrupts(target, arc->irq_state)); + else + CHECK_RETVAL(arc_enable_interrupts(target, !debug_execution)); + + target->debug_reason = DBG_REASON_NOTHALTED; + + /* ready to get us going again */ + target->state = TARGET_RUNNING; + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, &value)); + value &= ~SET_CORE_HALT_BIT; /* clear the HALT bit */ + CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, value)); + LOG_DEBUG("Core started to run"); + + /* registers are now invalid */ + register_cache_invalidate(arc->core_and_aux_cache); + + if (!debug_execution) { + target->state = TARGET_RUNNING; + CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED)); + LOG_DEBUG("target resumed at 0x%08" PRIx32, resume_pc); + } else { + target->state = TARGET_DEBUG_RUNNING; + CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED)); + LOG_DEBUG("target debug resumed at 0x%08" PRIx32, resume_pc); + } + + return ERROR_OK; +} + +static int arc_init_target(struct command_context *cmd_ctx, struct target *target) +{ + CHECK_RETVAL(arc_build_reg_cache(target)); + CHECK_RETVAL(arc_build_bcr_reg_cache(target)); + target->debug_reason = DBG_REASON_DBGRQ; + return ERROR_OK; +} + +static void arc_free_reg_cache(struct reg_cache *cache) +{ + free(cache->reg_list); + free(cache); +} + +static void arc_deinit_target(struct target *target) +{ + struct arc_common *arc = target_to_arc(target); + + LOG_DEBUG("deinitialization of target"); + if (arc->core_aux_cache_built) + arc_free_reg_cache(arc->core_and_aux_cache); + if (arc->bcr_cache_built) + arc_free_reg_cache(arc->bcr_cache); + + struct arc_reg_data_type *type, *n; + struct arc_reg_desc *desc, *k; + + /* Free arc-specific reg_data_types allocations*/ + list_for_each_entry_safe_reverse(type, n, &arc->reg_data_types, list) { + if (type->data_type.type_class == REG_TYPE_CLASS_STRUCT) { + free(type->data_type.reg_type_struct->fields); + free(type->bitfields); + free(type); + } else if (type->data_type.type_class == REG_TYPE_CLASS_FLAGS) { + free(type->data_type.reg_type_flags->fields); + free(type->bitfields); + free(type); + } + } + + /* Free standard_gdb_types reg_data_types allocations */ + type = list_first_entry(&arc->reg_data_types, struct arc_reg_data_type, list); + free(type); + + list_for_each_entry_safe(desc, k, &arc->aux_reg_descriptions, list) + free_reg_desc(desc); + + list_for_each_entry_safe(desc, k, &arc->core_reg_descriptions, list) + free_reg_desc(desc); + + list_for_each_entry_safe(desc, k, &arc->bcr_reg_descriptions, list) + free_reg_desc(desc); + + free(arc); +} + + +static int arc_target_create(struct target *target, Jim_Interp *interp) +{ + struct arc_common *arc = calloc(1, sizeof(*arc)); + + if (!arc) { + LOG_ERROR("Unable to allocate memory"); + return ERROR_FAIL; + } + + LOG_DEBUG("Entering"); + CHECK_RETVAL(arc_init_arch_info(target, arc, target->tap)); + + return ERROR_OK; +} + + +/* ARC v2 target */ +struct target_type arcv2_target = { + .name = "arcv2", + + .poll = arc_poll, + + .arch_state = arc_arch_state, + + /* TODO That seems like something similiar to metaware hostlink, so perhaps + * we can exploit this in the future. */ + .target_request_data = NULL, + + .halt = arc_halt, + .resume = arc_resume, + .step = NULL, + + .assert_reset = arc_assert_reset, + .deassert_reset = arc_deassert_reset, + + /* TODO Implement soft_reset_halt */ + .soft_reset_halt = NULL, + + .get_gdb_reg_list = arc_get_gdb_reg_list, + + .read_memory = arc_mem_read, + .write_memory = arc_mem_write, + .checksum_memory = NULL, + .blank_check_memory = NULL, + + .add_breakpoint = NULL, + .add_context_breakpoint = NULL, + .add_hybrid_breakpoint = NULL, + .remove_breakpoint = NULL, + .add_watchpoint = NULL, + .remove_watchpoint = NULL, + .hit_watchpoint = NULL, + + .run_algorithm = NULL, + .start_algorithm = NULL, + .wait_algorithm = NULL, + + .commands = arc_monitor_command_handlers, + + .target_create = arc_target_create, + .init_target = arc_init_target, + .deinit_target = arc_deinit_target, + .examine = arc_examine, + + .virt2phys = NULL, + .read_phys_memory = NULL, + .write_phys_memory = NULL, + .mmu = NULL, +}; diff --git a/src/target/arc.h b/src/target/arc.h new file mode 100644 index 000000000..311648e15 --- /dev/null +++ b/src/target/arc.h @@ -0,0 +1,212 @@ +/*************************************************************************** + * Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. * + * Frank Dols * + * Mischa Jonker * + * Anton Kolesov * + * Evgeniy Didin * + * * + * SPDX-License-Identifier: GPL-2.0-or-later * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_ARC_H +#define OPENOCD_TARGET_ARC_H + +#include +#include + +#include "algorithm.h" +#include "breakpoints.h" +#include "jtag/interface.h" +#include "register.h" +#include "target.h" +#include "target_request.h" +#include "target_type.h" +#include "helper/bits.h" + +#include "arc_jtag.h" +#include "arc_cmd.h" +#include "arc_mem.h" + +#define ARC_COMMON_MAGIC 0xB32EB324 /* just a unique number */ + +#define AUX_DEBUG_REG 0x5 +#define AUX_PC_REG 0x6 +#define AUX_STATUS32_REG 0xA + +#define SET_CORE_FORCE_HALT BIT(1) +#define SET_CORE_HALT_BIT BIT(0) /* STATUS32[0] = H field */ +#define SET_CORE_ENABLE_INTERRUPTS BIT(31) + +#define AUX_STATUS32_REG_HALT_BIT BIT(0) +#define AUX_STATUS32_REG_IE_BIT BIT(31) /* STATUS32[31] = IE field */ + +/* Reserved core registers */ +#define CORE_R61_NUM (61) +#define CORE_R62_NUM (62) + +#define CORE_REG_MAX_NUMBER (63) + +/* Limit reg_type/reg_type_field name to 20 symbols */ +#define REG_TYPE_MAX_NAME_LENGTH 20 + +struct arc_reg_bitfield { + struct reg_data_type_bitfield bitfield; + char name[REG_TYPE_MAX_NAME_LENGTH]; +}; +/* Register data type */ +struct arc_reg_data_type { + struct list_head list; + struct reg_data_type data_type; + struct reg_data_type_flags data_type_flags; + struct reg_data_type_struct data_type_struct; + char data_type_id[REG_TYPE_MAX_NAME_LENGTH]; + struct arc_reg_bitfield *bitfields; +}; + + + +/* Standard GDB register types */ +static const struct reg_data_type standard_gdb_types[] = { + { .type = REG_TYPE_INT, .id = "int" }, + { .type = REG_TYPE_INT8, .id = "int8" }, + { .type = REG_TYPE_INT16, .id = "int16" }, + { .type = REG_TYPE_INT32, .id = "int32" }, + { .type = REG_TYPE_INT64, .id = "int64" }, + { .type = REG_TYPE_INT128, .id = "int128" }, + { .type = REG_TYPE_UINT8, .id = "uint8" }, + { .type = REG_TYPE_UINT16, .id = "uint16" }, + { .type = REG_TYPE_UINT32, .id = "uint32" }, + { .type = REG_TYPE_UINT64, .id = "uint64" }, + { .type = REG_TYPE_UINT128, .id = "uint128" }, + { .type = REG_TYPE_CODE_PTR, .id = "code_ptr" }, + { .type = REG_TYPE_DATA_PTR, .id = "data_ptr" }, + { .type = REG_TYPE_FLOAT, .id = "float" }, + { .type = REG_TYPE_IEEE_SINGLE, .id = "ieee_single" }, + { .type = REG_TYPE_IEEE_DOUBLE, .id = "ieee_double" }, +}; + + +struct arc_common { + uint32_t common_magic; + + struct arc_jtag jtag_info; + + struct reg_cache *core_and_aux_cache; + struct reg_cache *bcr_cache; + + /* Indicate if cach was built (for deinit function) */ + bool core_aux_cache_built; + bool bcr_cache_built; + /* Closely Coupled memory(CCM) regions for performance-critical + * code (optional). */ + uint32_t iccm0_start; + uint32_t iccm0_end; + uint32_t iccm1_start; + uint32_t iccm1_end; + uint32_t dccm_start; + uint32_t dccm_end; + + int irq_state; + + /* Register descriptions */ + struct list_head reg_data_types; + struct list_head core_reg_descriptions; + struct list_head aux_reg_descriptions; + struct list_head bcr_reg_descriptions; + unsigned long num_regs; + unsigned long num_core_regs; + unsigned long num_aux_regs; + unsigned long num_bcr_regs; + unsigned long last_general_reg; + + /* PC register location in register cache. */ + unsigned long pc_index_in_cache; + /* DEBUG register location in register cache. */ + unsigned long debug_index_in_cache; +}; + +/* Borrowed from nds32.h */ +#define CHECK_RETVAL(action) \ + do { \ + int __retval = (action); \ + if (__retval != ERROR_OK) { \ + LOG_DEBUG("error while calling \"%s\"", \ + # action); \ + return __retval; \ + } \ + } while (0) + +#define JIM_CHECK_RETVAL(action) \ + do { \ + int __retval = (action); \ + if (__retval != JIM_OK) { \ + LOG_DEBUG("error while calling \"%s\"", \ + # action); \ + return __retval; \ + } \ + } while (0) + +static inline struct arc_common *target_to_arc(struct target *target) +{ + return target->arch_info; +} + + +/* ARC Register description */ +struct arc_reg_desc { + + struct target *target; + + /* Register name */ + char *name; + + /* Actual place of storing reg_value */ + uint8_t reg_value[4]; + + /* Actual place of storing register feature */ + struct reg_feature feature; + + /* GDB XML feature */ + char *gdb_xml_feature; + + /* Is this a register in g/G-packet? */ + bool is_general; + + /* Architectural number: core reg num or AUX reg num */ + uint32_t arch_num; + + /* Core or AUX register? */ + bool is_core; + + /* Build configuration register? */ + bool is_bcr; + + /* Data type */ + struct reg_data_type *data_type; + + struct list_head list; +}; + +/* Error codes */ +#define ERROR_ARC_REGISTER_NOT_FOUND (-700) +#define ERROR_ARC_REGISTER_FIELD_NOT_FOUND (-701) +#define ERROR_ARC_REGISTER_IS_NOT_STRUCT (-702) +#define ERROR_ARC_FIELD_IS_NOT_BITFIELD (-703) +#define ERROR_ARC_REGTYPE_NOT_FOUND (-704) + +void free_reg_desc(struct arc_reg_desc *r); + + +void arc_reg_data_type_add(struct target *target, + struct arc_reg_data_type *data_type); + +int arc_reg_add(struct target *target, struct arc_reg_desc *arc_reg, + const char * const type_name, const size_t type_name_len); + +struct reg *arc_reg_get_by_name(struct reg_cache *first, + const char *name, bool search_all); + +int arc_reg_get_field(struct target *target, const char *reg_name, + const char *field_name, uint32_t *value_ptr); + +#endif /* OPENOCD_TARGET_ARC_H */ diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c new file mode 100644 index 000000000..3f6caf751 --- /dev/null +++ b/src/target/arc_cmd.c @@ -0,0 +1,977 @@ +/*************************************************************************** + * Copyright (C) 2013-2015,2019-2020 Synopsys, Inc. * + * Frank Dols * + * Mischa Jonker * + * Anton Kolesov * + * Evgeniy Didin * + * * + * SPDX-License-Identifier: GPL-2.0-or-later * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arc.h" + +/* -------------------------------------------------------------------------- + * + * ARC targets expose command interface. + * It can be accessed via GDB through the (gdb) monitor command. + * + * ------------------------------------------------------------------------- */ + + +static int arc_cmd_jim_get_uint32(Jim_GetOptInfo *goi, uint32_t *value) +{ + jim_wide value_wide; + JIM_CHECK_RETVAL(Jim_GetOpt_Wide(goi, &value_wide)); + *value = (uint32_t)value_wide; + return JIM_OK; +} + +enum add_reg_types { + CFG_ADD_REG_TYPE_FLAG, + CFG_ADD_REG_TYPE_STRUCT, +}; +/* Add flags register data type */ +enum add_reg_type_flags { + CFG_ADD_REG_TYPE_FLAGS_NAME, + CFG_ADD_REG_TYPE_FLAGS_FLAG, +}; + +static Jim_Nvp nvp_add_reg_type_flags_opts[] = { + { .name = "-name", .value = CFG_ADD_REG_TYPE_FLAGS_NAME }, + { .name = "-flag", .value = CFG_ADD_REG_TYPE_FLAGS_FLAG }, + { .name = NULL, .value = -1 } +}; + +/* Helper function to check if all field required for register + * are set up */ +static const char *validate_register(const struct arc_reg_desc * const reg, bool arch_num_set) +{ + /* Check that required fields are set */ + if (!reg->name) + return "-name option is required"; + if (!reg->gdb_xml_feature) + return "-feature option is required"; + if (!arch_num_set) + return "-num option is required"; + if (reg->is_bcr && reg->is_core) + return "Register cannot be both -core and -bcr."; + return NULL; +} + +/* Helper function to read the name of register type or register from + * configure files */ +static int jim_arc_read_reg_name_field(Jim_GetOptInfo *goi, + const char **name, int *name_len) +{ + int e = JIM_OK; + + if (!goi->argc) { + Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-name ..."); + return JIM_ERR; + } + e = Jim_GetOpt_String(goi, name, name_len); + return e; +} + +/* Helper function to read bitfields/flags of register type. */ +static int jim_arc_read_reg_type_field(Jim_GetOptInfo *goi, const char **field_name, int *field_name_len, + struct arc_reg_bitfield *bitfields, int cur_field, int type) +{ + jim_wide start_pos, end_pos; + + int e = JIM_OK; + if ((type == CFG_ADD_REG_TYPE_STRUCT && goi->argc < 3) || + (type == CFG_ADD_REG_TYPE_FLAG && goi->argc < 2)) { + Jim_SetResultFormatted(goi->interp, "Not enough argmunets after -flag/-bitfield"); + return JIM_ERR; + } + + e = Jim_GetOpt_String(goi, field_name, field_name_len); + if (e != JIM_OK) + return e; + + /* read start position of bitfield/flag */ + e = Jim_GetOpt_Wide(goi, &start_pos); + if (e != JIM_OK) + return e; + + end_pos = start_pos; + + /* Check if any argnuments remain, + * set bitfields[cur_field].end if flag is multibit */ + if (goi->argc > 0) + /* Check current argv[0], if it is equal to "-flag", + * than bitfields[cur_field].end remains start */ + if ((strcmp(Jim_String(goi->argv[0]), "-flag") && type == CFG_ADD_REG_TYPE_FLAG) + || (type == CFG_ADD_REG_TYPE_STRUCT)) { + e = Jim_GetOpt_Wide(goi, &end_pos); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi->interp, "Error reading end position"); + return e; + } + } + + bitfields[cur_field].bitfield.start = start_pos; + bitfields[cur_field].bitfield.end = end_pos; + if ((end_pos != start_pos) || (type == CFG_ADD_REG_TYPE_STRUCT)) + bitfields[cur_field].bitfield.type = REG_TYPE_INT; + return e; +} + +static int jim_arc_add_reg_type_flags(Jim_Interp *interp, int argc, + Jim_Obj * const *argv) +{ + Jim_GetOptInfo goi; + JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + + LOG_DEBUG("-"); + + struct command_context *ctx; + struct target *target; + + ctx = current_command_context(interp); + assert(ctx); + target = get_current_target(ctx); + if (!target) { + Jim_SetResultFormatted(goi.interp, "No current target"); + return JIM_ERR; + } + + int e = JIM_OK; + + /* Check if the amount of argnuments is not zero */ + if (goi.argc <= 0) { + Jim_SetResultFormatted(goi.interp, "The command has no argnuments"); + return JIM_ERR; + } + + /* Estimate number of registers as (argc - 2)/3 as each -flag option has 2 + * arguments while -name is required. */ + unsigned int fields_sz = (goi.argc - 2) / 3; + unsigned int cur_field = 0; + + /* Tha maximum amount of bitfilds is 32 */ + if (fields_sz > 32) { + Jim_SetResultFormatted(goi.interp, "The amount of bitfields exceed 32"); + return JIM_ERR; + } + + struct arc_reg_data_type *type = calloc(1, sizeof(*type)); + struct reg_data_type_flags *flags = &type->data_type_flags; + struct reg_data_type_flags_field *fields = calloc(fields_sz, sizeof(*fields)); + struct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*type)); + if (!(type && fields && bitfields)) { + Jim_SetResultFormatted(goi.interp, "Failed to allocate memory."); + goto fail; + } + + /* Initialize type */ + type->bitfields = bitfields; + type->data_type.id = type->data_type_id; + type->data_type.type = REG_TYPE_ARCH_DEFINED; + type->data_type.type_class = REG_TYPE_CLASS_FLAGS; + type->data_type.reg_type_flags = flags; + flags->size = 4; /* For now ARC has only 32-bit registers */ + + while (goi.argc > 0 && e == JIM_OK) { + Jim_Nvp *n; + e = Jim_GetOpt_Nvp(&goi, nvp_add_reg_type_flags_opts, &n); + if (e != JIM_OK) { + Jim_GetOpt_NvpUnknown(&goi, nvp_add_reg_type_flags_opts, 0); + continue; + } + + switch (n->value) { + case CFG_ADD_REG_TYPE_FLAGS_NAME: + { + const char *name = NULL; + int name_len = 0; + + e = jim_arc_read_reg_name_field(&goi, &name, &name_len); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi.interp, "Unable to read reg name."); + goto fail; + } + + if (name_len > REG_TYPE_MAX_NAME_LENGTH) { + Jim_SetResultFormatted(goi.interp, "Reg type name is too big."); + goto fail; + } + + strncpy((void *)type->data_type.id, name, name_len); + if (!type->data_type.id) { + Jim_SetResultFormatted(goi.interp, "Unable to setup reg type name."); + goto fail; + } + + break; + } + + case CFG_ADD_REG_TYPE_FLAGS_FLAG: + { + const char *field_name = NULL; + int field_name_len = 0; + + e = jim_arc_read_reg_type_field(&goi, &field_name, &field_name_len, bitfields, + cur_field, CFG_ADD_REG_TYPE_FLAG); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi.interp, "Unable to add reg_type_flag field."); + goto fail; + } + + if (field_name_len > REG_TYPE_MAX_NAME_LENGTH) { + Jim_SetResultFormatted(goi.interp, "Reg type field_name_len is too big."); + goto fail; + } + + fields[cur_field].name = bitfields[cur_field].name; + strncpy(bitfields[cur_field].name, field_name, field_name_len); + if (!fields[cur_field].name) { + Jim_SetResultFormatted(goi.interp, "Unable to setup field name. "); + goto fail; + } + + fields[cur_field].bitfield = &(bitfields[cur_field].bitfield); + if (cur_field > 0) + fields[cur_field - 1].next = &(fields[cur_field]); + else + flags->fields = fields; + + cur_field += 1; + break; + } + } + } + + if (!type->data_type.id) { + Jim_SetResultFormatted(goi.interp, "-name is a required option"); + goto fail; + } + + arc_reg_data_type_add(target, type); + + LOG_DEBUG("added flags type {name=%s}", type->data_type.id); + + return JIM_OK; +fail: + free(type); + free(fields); + free(bitfields); + + return JIM_ERR; +} + +/* Add struct register data type */ +enum add_reg_type_struct { + CFG_ADD_REG_TYPE_STRUCT_NAME, + CFG_ADD_REG_TYPE_STRUCT_BITFIELD, +}; + +static Jim_Nvp nvp_add_reg_type_struct_opts[] = { + { .name = "-name", .value = CFG_ADD_REG_TYPE_STRUCT_NAME }, + { .name = "-bitfield", .value = CFG_ADD_REG_TYPE_STRUCT_BITFIELD }, + { .name = NULL, .value = -1 } +}; + +static int jim_arc_set_aux_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +{ + + struct command_context *context; + struct target *target; + uint32_t regnum; + uint32_t value; + + Jim_GetOptInfo goi; + JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + + if (goi.argc != 2) { + Jim_SetResultFormatted(goi.interp, + "usage: %s ", Jim_GetString(argv[0], NULL)); + return JIM_ERR; + } + + context = current_command_context(interp); + assert(context); + + target = get_current_target(context); + if (!target) { + Jim_SetResultFormatted(goi.interp, "No current target"); + return JIM_ERR; + } + + /* Register number */ + JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); + + /* Register value */ + JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, &value)); + + struct arc_common *arc = target_to_arc(target); + assert(arc); + + CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, regnum, value)); + + return ERROR_OK; +} + +static int jim_arc_get_aux_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +{ + struct command_context *context; + struct target *target; + uint32_t regnum; + uint32_t value; + + Jim_GetOptInfo goi; + JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + + if (goi.argc != 1) { + Jim_SetResultFormatted(goi.interp, + "usage: %s ", Jim_GetString(argv[0], NULL)); + return JIM_ERR; + } + + context = current_command_context(interp); + assert(context); + + target = get_current_target(context); + if (!target) { + Jim_SetResultFormatted(goi.interp, "No current target"); + return JIM_ERR; + } + + /* Register number */ + JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); + + struct arc_common *arc = target_to_arc(target); + assert(arc); + + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, regnum, &value)); + Jim_SetResultInt(interp, value); + + return ERROR_OK; +} + +static int jim_arc_get_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +{ + struct command_context *context; + struct target *target; + uint32_t regnum; + uint32_t value; + + Jim_GetOptInfo goi; + JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + + if (goi.argc != 1) { + Jim_SetResultFormatted(goi.interp, + "usage: %s ", Jim_GetString(argv[0], NULL)); + return JIM_ERR; + } + + context = current_command_context(interp); + assert(context); + + target = get_current_target(context); + if (!target) { + Jim_SetResultFormatted(goi.interp, "No current target"); + return JIM_ERR; + } + + /* Register number */ + JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); + if (regnum > CORE_REG_MAX_NUMBER || regnum == CORE_R61_NUM || regnum == CORE_R62_NUM) { + Jim_SetResultFormatted(goi.interp, "Core register number %i " \ + "is invalid. Must less then 64 and not 61 and 62.", regnum); + return JIM_ERR; + } + + struct arc_common *arc = target_to_arc(target); + assert(arc); + + /* Read value */ + CHECK_RETVAL(arc_jtag_read_core_reg_one(&arc->jtag_info, regnum, &value)); + Jim_SetResultInt(interp, value); + + return ERROR_OK; +} + +static int jim_arc_set_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +{ + struct command_context *context; + struct target *target; + uint32_t regnum; + uint32_t value; + + Jim_GetOptInfo goi; + JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + + if (goi.argc != 2) { + Jim_SetResultFormatted(goi.interp, + "usage: %s ", Jim_GetString(argv[0], NULL)); + return JIM_ERR; + } + + context = current_command_context(interp); + assert(context); + + target = get_current_target(context); + if (!target) { + Jim_SetResultFormatted(goi.interp, "No current target"); + return JIM_ERR; + } + + /* Register number */ + JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); + if (regnum > CORE_REG_MAX_NUMBER || regnum == CORE_R61_NUM || regnum == CORE_R62_NUM) { + Jim_SetResultFormatted(goi.interp, "Core register number %i " \ + "is invalid. Must less then 64 and not 61 and 62.", regnum); + return JIM_ERR; + } + + /* Register value */ + JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, &value)); + + struct arc_common *arc = target_to_arc(target); + assert(arc); + + CHECK_RETVAL(arc_jtag_write_core_reg_one(&arc->jtag_info, regnum, value)); + + return ERROR_OK; +} + +static const struct command_registration arc_jtag_command_group[] = { + { + .name = "get-aux-reg", + .jim_handler = jim_arc_get_aux_reg, + .mode = COMMAND_EXEC, + .help = "Get AUX register by number. This command does a " \ + "raw JTAG request that bypasses OpenOCD register cache "\ + "and thus is unsafe and can have unexpected consequences. "\ + "Use at your own risk.", + .usage = "arc jtag get-aux-reg " + }, + { + .name = "set-aux-reg", + .jim_handler = jim_arc_set_aux_reg, + .mode = COMMAND_EXEC, + .help = "Set AUX register by number. This command does a " \ + "raw JTAG request that bypasses OpenOCD register cache "\ + "and thus is unsafe and can have unexpected consequences. "\ + "Use at your own risk.", + .usage = "arc jtag set-aux-reg " + }, + { + .name = "get-core-reg", + .jim_handler = jim_arc_get_core_reg, + .mode = COMMAND_EXEC, + .help = "Get/Set core register by number. This command does a " \ + "raw JTAG request that bypasses OpenOCD register cache "\ + "and thus is unsafe and can have unexpected consequences. "\ + "Use at your own risk.", + .usage = "arc jtag get-core-reg []" + }, + { + .name = "set-core-reg", + .jim_handler = jim_arc_set_core_reg, + .mode = COMMAND_EXEC, + .help = "Get/Set core register by number. This command does a " \ + "raw JTAG request that bypasses OpenOCD register cache "\ + "and thus is unsafe and can have unexpected consequences. "\ + "Use at your own risk.", + .usage = "arc jtag set-core-reg []" + }, + COMMAND_REGISTRATION_DONE +}; + + +/* This function supports only bitfields. */ +static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc, + Jim_Obj * const *argv) +{ + Jim_GetOptInfo goi; + JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + + LOG_DEBUG("-"); + + struct command_context *ctx; + struct target *target; + + ctx = current_command_context(interp); + assert(ctx); + target = get_current_target(ctx); + if (!target) { + Jim_SetResultFormatted(goi.interp, "No current target"); + return JIM_ERR; + } + + int e = JIM_OK; + + /* Check if the amount of argnuments is not zero */ + if (goi.argc <= 0) { + Jim_SetResultFormatted(goi.interp, "The command has no argnuments"); + return JIM_ERR; + } + + /* Estimate number of registers as (argc - 2)/4 as each -bitfield option has 3 + * arguments while -name is required. */ + unsigned int fields_sz = (goi.argc - 2) / 4; + unsigned int cur_field = 0; + + /* Tha maximum amount of bitfilds is 32 */ + if (fields_sz > 32) { + Jim_SetResultFormatted(goi.interp, "The amount of bitfields exceed 32"); + return JIM_ERR; + } + + struct arc_reg_data_type *type = calloc(1, sizeof(*type)); + struct reg_data_type_struct *struct_type = &type->data_type_struct; + struct reg_data_type_struct_field *fields = calloc(fields_sz, sizeof(*fields)); + struct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*type)); + if (!(type && fields && bitfields)) { + Jim_SetResultFormatted(goi.interp, "Failed to allocate memory."); + goto fail; + } + + /* Initialize type */ + type->data_type.id = type->data_type_id; + type->bitfields = bitfields; + type->data_type.type = REG_TYPE_ARCH_DEFINED; + type->data_type.type_class = REG_TYPE_CLASS_STRUCT; + type->data_type.reg_type_struct = struct_type; + struct_type->size = 4; /* For now ARC has only 32-bit registers */ + + while (goi.argc > 0 && e == JIM_OK) { + Jim_Nvp *n; + e = Jim_GetOpt_Nvp(&goi, nvp_add_reg_type_struct_opts, &n); + if (e != JIM_OK) { + Jim_GetOpt_NvpUnknown(&goi, nvp_add_reg_type_struct_opts, 0); + continue; + } + + switch (n->value) { + case CFG_ADD_REG_TYPE_STRUCT_NAME: + { + const char *name = NULL; + int name_len = 0; + + e = jim_arc_read_reg_name_field(&goi, &name, &name_len); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi.interp, "Unable to read reg name."); + goto fail; + } + + if (name_len > REG_TYPE_MAX_NAME_LENGTH) { + Jim_SetResultFormatted(goi.interp, "Reg type name is too big."); + goto fail; + } + + strncpy((void *)type->data_type.id, name, name_len); + if (!type->data_type.id) { + Jim_SetResultFormatted(goi.interp, "Unable to setup reg type name."); + goto fail; + } + + break; + } + case CFG_ADD_REG_TYPE_STRUCT_BITFIELD: + { + const char *field_name = NULL; + int field_name_len = 0; + e = jim_arc_read_reg_type_field(&goi, &field_name, &field_name_len, bitfields, + cur_field, CFG_ADD_REG_TYPE_STRUCT); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi.interp, "Unable to add reg_type_struct field."); + goto fail; + } + + if (field_name_len > REG_TYPE_MAX_NAME_LENGTH) { + Jim_SetResultFormatted(goi.interp, "Reg type field_name_len is too big."); + goto fail; + } + + fields[cur_field].name = bitfields[cur_field].name; + strncpy(bitfields[cur_field].name, field_name, field_name_len); + if (!fields[cur_field].name) { + Jim_SetResultFormatted(goi.interp, "Unable to setup field name. "); + goto fail; + } + + fields[cur_field].bitfield = &(bitfields[cur_field].bitfield); + fields[cur_field].use_bitfields = true; + if (cur_field > 0) + fields[cur_field - 1].next = &(fields[cur_field]); + else + struct_type->fields = fields; + + cur_field += 1; + + break; + } + } + } + + if (!type->data_type.id) { + Jim_SetResultFormatted(goi.interp, "-name is a required option"); + goto fail; + } + + arc_reg_data_type_add(target, type); + LOG_DEBUG("added struct type {name=%s}", type->data_type.id); + return JIM_OK; + +fail: + free(type); + free(fields); + free(bitfields); + + return JIM_ERR; +} + +/* Add register */ +enum opts_add_reg { + CFG_ADD_REG_NAME, + CFG_ADD_REG_ARCH_NUM, + CFG_ADD_REG_IS_CORE, + CFG_ADD_REG_IS_BCR, + CFG_ADD_REG_GDB_FEATURE, + CFG_ADD_REG_TYPE, + CFG_ADD_REG_GENERAL, +}; + +static Jim_Nvp opts_nvp_add_reg[] = { + { .name = "-name", .value = CFG_ADD_REG_NAME }, + { .name = "-num", .value = CFG_ADD_REG_ARCH_NUM }, + { .name = "-core", .value = CFG_ADD_REG_IS_CORE }, + { .name = "-bcr", .value = CFG_ADD_REG_IS_BCR }, + { .name = "-feature", .value = CFG_ADD_REG_GDB_FEATURE }, + { .name = "-type", .value = CFG_ADD_REG_TYPE }, + { .name = "-g", .value = CFG_ADD_REG_GENERAL }, + { .name = NULL, .value = -1 } +}; + +void free_reg_desc(struct arc_reg_desc *r) +{ + free(r->name); + free(r->gdb_xml_feature); + free(r); +} + +static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +{ + Jim_GetOptInfo goi; + JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + + struct arc_reg_desc *reg = calloc(1, sizeof(*reg)); + if (!reg) { + Jim_SetResultFormatted(goi.interp, "Failed to allocate memory."); + return JIM_ERR; + } + + /* There is no architecture number that we could treat as invalid, so + * separate variable requried to ensure that arch num has been set. */ + bool arch_num_set = false; + const char *type_name = "int"; /* Default type */ + int type_name_len = strlen(type_name); + int e = ERROR_OK; + + /* At least we need to specify 4 parameters: name, number, type and gdb_feature, + * which means there should be 8 arguments */ + if (goi.argc < 8) { + free_reg_desc(reg); + Jim_SetResultFormatted(goi.interp, + "Should be at least 8 argnuments: -name " + "-num -type -feature ."); + return JIM_ERR; + } + + /* Parse options. */ + while (goi.argc > 0) { + Jim_Nvp *n; + e = Jim_GetOpt_Nvp(&goi, opts_nvp_add_reg, &n); + if (e != JIM_OK) { + Jim_GetOpt_NvpUnknown(&goi, opts_nvp_add_reg, 0); + free_reg_desc(reg); + return e; + } + + switch (n->value) { + case CFG_ADD_REG_NAME: + { + const char *reg_name = NULL; + int reg_name_len = 0; + + e = jim_arc_read_reg_name_field(&goi, ®_name, ®_name_len); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi.interp, "Unable to read register name."); + free_reg_desc(reg); + return e; + } + + reg->name = strndup(reg_name, reg_name_len); + break; + } + case CFG_ADD_REG_IS_CORE: + reg->is_core = true; + break; + case CFG_ADD_REG_IS_BCR: + reg->is_bcr = true; + break; + case CFG_ADD_REG_ARCH_NUM: + { + jim_wide archnum; + + if (!goi.argc) { + free_reg_desc(reg); + Jim_WrongNumArgs(interp, goi.argc, goi.argv, "-num ..."); + return JIM_ERR; + } + + e = Jim_GetOpt_Wide(&goi, &archnum); + if (e != JIM_OK) { + free_reg_desc(reg); + return e; + } + + reg->arch_num = archnum; + arch_num_set = true; + break; + } + case CFG_ADD_REG_GDB_FEATURE: + { + const char *feature = NULL; + int feature_len = 0; + + e = jim_arc_read_reg_name_field(&goi, &feature, &feature_len); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi.interp, "Unable to read gdb_feature."); + free_reg_desc(reg); + return e; + } + + reg->gdb_xml_feature = strndup(feature, feature_len); + break; + } + case CFG_ADD_REG_TYPE: + e = jim_arc_read_reg_name_field(&goi, &type_name, &type_name_len); + if (e != JIM_OK) { + Jim_SetResultFormatted(goi.interp, "Unable to read register type."); + free_reg_desc(reg); + return e; + } + + break; + case CFG_ADD_REG_GENERAL: + reg->is_general = true; + break; + default: + LOG_DEBUG("Error: Unknown parameter"); + free_reg_desc(reg); + return JIM_ERR; + } + } + + /* Check that required fields are set */ + const char * const errmsg = validate_register(reg, arch_num_set); + if (errmsg) { + Jim_SetResultFormatted(goi.interp, errmsg); + free_reg_desc(reg); + return JIM_ERR; + } + + /* Add new register */ + struct command_context *ctx; + struct target *target; + + ctx = current_command_context(interp); + assert(ctx); + target = get_current_target(ctx); + if (!target) { + Jim_SetResultFormatted(goi.interp, "No current target"); + return JIM_ERR; + } + + reg->target = target; + + e = arc_reg_add(target, reg, type_name, type_name_len); + if (e == ERROR_ARC_REGTYPE_NOT_FOUND) { + Jim_SetResultFormatted(goi.interp, + "Cannot find type `%s' for register `%s'.", + type_name, reg->name); + free_reg_desc(reg); + return JIM_ERR; + } + + return e; +} + +/* arc set-reg-exists ($reg_name)+ + * Accepts any amount of register names - will set them as existing in a loop.*/ +COMMAND_HANDLER(arc_set_reg_exists) +{ + struct target * const target = get_current_target(CMD_CTX); + if (!target) { + command_print(CMD, "Unable to get current target."); + return JIM_ERR; + } + + if (!CMD_ARGC) { + command_print(CMD, "At least one register name must be specified."); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + for (unsigned int i = 0; i < CMD_ARGC; i++) { + const char * const reg_name = CMD_ARGV[i]; + struct reg * const r = arc_reg_get_by_name(target->reg_cache, reg_name, true); + + if (!r) { + command_print(CMD, "Register `%s' is not found.", reg_name); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + r->exist = true; + } + + return JIM_OK; +} + +/* arc reg-field ($reg_name) ($reg_field) + * Reads struct type register field */ +static int jim_arc_get_reg_field(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +{ + Jim_GetOptInfo goi; + const char *reg_name, *field_name; + uint32_t value; + int retval; + + JIM_CHECK_RETVAL(Jim_GetOpt_Setup(&goi, interp, argc-1, argv+1)); + + LOG_DEBUG("Reading register field"); + if (goi.argc != 2) { + if (!goi.argc) + Jim_WrongNumArgs(interp, goi.argc, goi.argv, " "); + else if (goi.argc == 1) + Jim_WrongNumArgs(interp, goi.argc, goi.argv, ""); + else + Jim_WrongNumArgs(interp, goi.argc, goi.argv, " "); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + JIM_CHECK_RETVAL(Jim_GetOpt_String(&goi, ®_name, NULL)); + JIM_CHECK_RETVAL(Jim_GetOpt_String(&goi, &field_name, NULL)); + assert(reg_name); + assert(field_name); + + struct command_context * const ctx = current_command_context(interp); + assert(ctx); + struct target * const target = get_current_target(ctx); + if (!target) { + Jim_SetResultFormatted(goi.interp, "No current target"); + return JIM_ERR; + } + + retval = arc_reg_get_field(target, reg_name, field_name, &value); + + switch (retval) { + case ERROR_OK: + break; + case ERROR_ARC_REGISTER_NOT_FOUND: + Jim_SetResultFormatted(goi.interp, + "Register `%s' has not been found.", reg_name); + return ERROR_COMMAND_ARGUMENT_INVALID; + case ERROR_ARC_REGISTER_IS_NOT_STRUCT: + Jim_SetResultFormatted(goi.interp, + "Register `%s' must have 'struct' type.", reg_name); + return ERROR_COMMAND_ARGUMENT_INVALID; + case ERROR_ARC_REGISTER_FIELD_NOT_FOUND: + Jim_SetResultFormatted(goi.interp, + "Field `%s' has not been found in register `%s'.", + field_name, reg_name); + return ERROR_COMMAND_ARGUMENT_INVALID; + case ERROR_ARC_FIELD_IS_NOT_BITFIELD: + Jim_SetResultFormatted(goi.interp, + "Field `%s' is not a 'bitfield' field in a structure.", + field_name); + return ERROR_COMMAND_ARGUMENT_INVALID; + default: + /* Pass through other errors. */ + return retval; + } + + Jim_SetResultInt(interp, value); + + return JIM_OK; +} + +/* ----- Exported target commands ------------------------------------------ */ + +static const struct command_registration arc_core_command_handlers[] = { +{ + .name = "add-reg-type-flags", + .jim_handler = jim_arc_add_reg_type_flags, + .mode = COMMAND_CONFIG, + .usage = "arc ardd-reg-type-flags -name -flag " + "[-flag ]...", + .help = "Add new 'flags' register data type. Only single bit flags " + "are supported. Type name is global. Bitsize of register is fixed " + "at 32 bits.", + }, + { + .name = "add-reg-type-struct", + .jim_handler = jim_arc_add_reg_type_struct, + .mode = COMMAND_CONFIG, + .usage = "arc add-reg-type-struct -name -bitfield " + "[-bitfield ]...", + .help = "Add new 'struct' register data type. Only bit-fields are " + "supported so far, which means that for each bitfield start and end " + "position bits must be specified. GDB also support type-fields, " + "where common type can be used instead. Type name is global. Bitsize of " + "register is fixed at 32 bits.", + }, + { + .name = "add-reg", + .jim_handler = jim_arc_add_reg, + .mode = COMMAND_CONFIG, + .usage = "arc add-reg -name -num -feature [-gdbnum ] " + "[-core|-bcr] [-type ] [-g]", + .help = "Add new register. Name, architectural number and feature name " + "are requried options. GDB regnum will default to previous register " + "(gdbnum + 1) and shouldn't be specified in most cases. Type " + "defaults to default GDB 'int'.", + }, + { + .name = "set-reg-exists", + .handler = arc_set_reg_exists, + .mode = COMMAND_ANY, + .usage = "arc set-reg-exists []...", + .help = "Set that register exists. Accepts multiple register names as " + "arguments.", + }, + { + .name = "get-reg-field", + .jim_handler = jim_arc_get_reg_field, + .mode = COMMAND_ANY, + .usage = "arc get-reg-field ", + .help = "Returns value of field in a register with 'struct' type.", + }, + { + .name = "jtag", + .mode = COMMAND_ANY, + .help = "ARC JTAG specific commands", + .usage = "", + .chain = arc_jtag_command_group, + }, + COMMAND_REGISTRATION_DONE +}; + +const struct command_registration arc_monitor_command_handlers[] = { + { + .name = "arc", + .mode = COMMAND_ANY, + .help = "ARC monitor command group", + .usage = "Help info ...", + .chain = arc_core_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; diff --git a/src/target/arc_cmd.h b/src/target/arc_cmd.h new file mode 100644 index 000000000..b2264eb94 --- /dev/null +++ b/src/target/arc_cmd.h @@ -0,0 +1,16 @@ +/*************************************************************************** + * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * + * Frank Dols * + * Mischa Jonker * + * Anton Kolesov * + * Evgeniy Didin * + * * + * SPDX-License-Identifier: GPL-2.0-or-later * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_ARC_CMD_H +#define OPENOCD_TARGET_ARC_CMD_H + +extern const struct command_registration arc_monitor_command_handlers[]; + +#endif /* OPENOCD_TARGET_ARC_CMD_H */ diff --git a/src/target/arc_jtag.c b/src/target/arc_jtag.c new file mode 100644 index 000000000..dd800a462 --- /dev/null +++ b/src/target/arc_jtag.c @@ -0,0 +1,542 @@ +/*************************************************************************** + * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * + * Frank Dols * + * Mischa Jonker * + * Anton Kolesov * + * Evgeniy Didin * + * * + * SPDX-License-Identifier: GPL-2.0-or-later * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arc.h" + +/* + * This functions sets instruction register in TAP. TAP end state is always + * IRPAUSE. + * + * @param jtag_info + * @param new_instr Instruction to write to instruction register. + */ +static void arc_jtag_enque_write_ir(struct arc_jtag *jtag_info, uint32_t + new_instr) +{ + uint32_t current_instr; + struct jtag_tap *tap; + uint8_t instr_buffer[sizeof(uint32_t)]; + + assert(jtag_info); + assert(jtag_info->tap); + + tap = jtag_info->tap; + + /* Do not set instruction if it is the same as current. */ + current_instr = buf_get_u32(tap->cur_instr, 0, tap->ir_length); + if (current_instr == new_instr) + return; + + struct scan_field field = { + .num_bits = tap->ir_length, + .out_value = instr_buffer + }; + buf_set_u32(instr_buffer, 0, field.num_bits, new_instr); + + /* From code in src/jtag/drivers/driver.c it look like that fields are + * copied so it is OK that field in this function is allocated in stack and + * thus this memory will be repurposed before jtag_execute_queue() will be + * invoked. */ + jtag_add_ir_scan(tap, &field, TAP_IRPAUSE); +} + +/** + * Read 4-byte word from data register. + * + * Unlike arc_jtag_write_data, this function returns byte-buffer, caller must + * convert this data to required format himself. This is done, because it is + * impossible to convert data before jtag_execute_queue() is invoked, so it + * cannot be done inside this function, so it has to operate with + * byte-buffers. Write function on the other hand can "write-and-forget", data + * is converted to byte-buffer before jtag_execute_queue(). + * + * @param jtag_info + * @param data Array of bytes to read into. + * @param end_state End state after reading. + */ +static void arc_jtag_enque_read_dr(struct arc_jtag *jtag_info, uint8_t *data, + tap_state_t end_state) +{ + + assert(jtag_info); + assert(jtag_info->tap); + + struct scan_field field = { + .num_bits = 32, + .in_value = data + }; + + jtag_add_dr_scan(jtag_info->tap, 1, &field, end_state); +} + +/** + * Write 4-byte word to data register. + * + * @param jtag_info + * @param data 4-byte word to write into data register. + * @param end_state End state after writing. + */ +static void arc_jtag_enque_write_dr(struct arc_jtag *jtag_info, uint32_t data, + tap_state_t end_state) +{ + uint8_t out_value[sizeof(uint32_t)]; + + assert(jtag_info); + assert(jtag_info->tap); + + buf_set_u32(out_value, 0, 32, data); + + struct scan_field field = { + .num_bits = 32, + .out_value = out_value + }; + + jtag_add_dr_scan(jtag_info->tap, 1, &field, end_state); +} + + +/** + * Set transaction in command register. This function sets instruction register + * and then transaction register, there is no need to invoke write_ir before + * invoking this function. + * + * @param jtag_info + * @param new_trans Transaction to write to transaction command register. + * @param end_state End state after writing. + */ +static void arc_jtag_enque_set_transaction(struct arc_jtag *jtag_info, + uint32_t new_trans, tap_state_t end_state) +{ + uint8_t out_value[sizeof(uint32_t)]; + + assert(jtag_info); + assert(jtag_info->tap); + + /* No need to do anything. */ + if (jtag_info->cur_trans == new_trans) + return; + + /* Set instruction. We used to call write_ir at upper levels, however + * write_ir-write_transaction were constantly in pair, so to avoid code + * duplication this function does it self. For this reasons it is "set" + * instead of "write". */ + arc_jtag_enque_write_ir(jtag_info, ARC_TRANSACTION_CMD_REG); + buf_set_u32(out_value, 0, ARC_TRANSACTION_CMD_REG_LENGTH, new_trans); + struct scan_field field = { + .num_bits = ARC_TRANSACTION_CMD_REG_LENGTH, + .out_value = out_value + }; + + jtag_add_dr_scan(jtag_info->tap, 1, &field, end_state); + jtag_info->cur_trans = new_trans; +} + +/** + * Run reset through transaction set. None of the previous + * settings/commands/etc. are used anymore (or no influence). + */ +static void arc_jtag_enque_reset_transaction(struct arc_jtag *jtag_info) +{ + arc_jtag_enque_set_transaction(jtag_info, ARC_JTAG_CMD_NOP, TAP_IDLE); +} + +static void arc_jtag_enque_status_read(struct arc_jtag * const jtag_info, + uint8_t * const buffer) +{ + assert(jtag_info); + assert(jtag_info->tap); + assert(buffer); + + /* first writin code(0x8) of jtag status register in IR */ + arc_jtag_enque_write_ir(jtag_info, ARC_JTAG_STATUS_REG); + /* Now reading dr performs jtag status register read */ + arc_jtag_enque_read_dr(jtag_info, buffer, TAP_IDLE); +} + +/* ----- Exported JTAG functions ------------------------------------------- */ + +int arc_jtag_startup(struct arc_jtag *jtag_info) +{ + assert(jtag_info); + + arc_jtag_enque_reset_transaction(jtag_info); + + return jtag_execute_queue(); +} + +/** Read STATUS register. */ +int arc_jtag_status(struct arc_jtag * const jtag_info, uint32_t * const value) +{ + uint8_t buffer[sizeof(uint32_t)]; + + assert(jtag_info); + assert(jtag_info->tap); + + /* Fill command queue. */ + arc_jtag_enque_reset_transaction(jtag_info); + arc_jtag_enque_status_read(jtag_info, buffer); + arc_jtag_enque_reset_transaction(jtag_info); + + /* Execute queue. */ + CHECK_RETVAL(jtag_execute_queue()); + + /* Parse output. */ + *value = buf_get_u32(buffer, 0, 32); + + return ERROR_OK; +} +/* Helper function: Adding read/write register operation to queue */ +static void arc_jtag_enque_register_rw(struct arc_jtag *jtag_info, uint32_t *addr, + uint8_t *read_buffer, const uint32_t *write_buffer, uint32_t count) +{ + uint32_t i; + + for (i = 0; i < count; i++) { + /* ARC jtag has optimization which is to increment ADDRESS_REG performing + * each transaction. Making sequential reads/writes we can set address for + * only first register in sequence, and than do read/write in cycle. */ + if (i == 0 || (addr[i] != addr[i-1] + 1)) { + arc_jtag_enque_write_ir(jtag_info, ARC_JTAG_ADDRESS_REG); + /* Going to TAP_IDLE state we initiate jtag transaction. + * Reading data we must go to TAP_IDLE, because further + * the data would be read. In case of write we go to TAP_DRPAUSE, + * because we need to write data to Data register first. */ + if (write_buffer) + arc_jtag_enque_write_dr(jtag_info, addr[i], TAP_DRPAUSE); + else + arc_jtag_enque_write_dr(jtag_info, addr[i], TAP_IDLE); + arc_jtag_enque_write_ir(jtag_info, ARC_JTAG_DATA_REG); + } + if (write_buffer) + arc_jtag_enque_write_dr(jtag_info, *(write_buffer + i), TAP_IDLE); + else + arc_jtag_enque_read_dr(jtag_info, read_buffer + i * 4, TAP_IDLE); + } + /* To prevent pollution of next regiter due to optimization it is necessary * + * to reset transaction */ + arc_jtag_enque_reset_transaction(jtag_info); +} + +/** + * Write registers. addr is an array of addresses, and those addresses can be + * in any order, though it is recommended that they are in sequential order + * where possible, as this reduces number of JTAG commands to transfer. + * + * @param jtag_info + * @param type Type of registers to write: core or aux. + * @param addr Array of registers numbers. + * @param count Amount of registers in arrays. + * @param values Array of register values. + */ +static int arc_jtag_write_registers(struct arc_jtag *jtag_info, uint32_t type, + uint32_t *addr, uint32_t count, const uint32_t *buffer) +{ + LOG_DEBUG("Writing to %s registers: addr[0]=0x%" PRIx32 ";count=%" PRIu32 + ";buffer[0]=0x%08" PRIx32, + (type == ARC_JTAG_CORE_REG ? "core" : "aux"), *addr, count, *buffer); + + if (!count) { + LOG_ERROR("Trying to write 0 registers"); + return ERROR_FAIL; + } + + arc_jtag_enque_reset_transaction(jtag_info); + + /* What registers are we writing to? */ + const uint32_t transaction = (type == ARC_JTAG_CORE_REG ? + ARC_JTAG_WRITE_TO_CORE_REG : ARC_JTAG_WRITE_TO_AUX_REG); + arc_jtag_enque_set_transaction(jtag_info, transaction, TAP_DRPAUSE); + + arc_jtag_enque_register_rw(jtag_info, addr, NULL, buffer, count); + + return jtag_execute_queue(); +} + +/** + * Read registers. addr is an array of addresses, and those addresses can be in + * any order, though it is recommended that they are in sequential order where + * possible, as this reduces number of JTAG commands to transfer. + * + * @param jtag_info + * @param type Type of registers to read: core or aux. + * @param addr Array of registers numbers. + * @param count Amount of registers in arrays. + * @param values Array of register values. + */ +static int arc_jtag_read_registers(struct arc_jtag *jtag_info, uint32_t type, + uint32_t *addr, uint32_t count, uint32_t *buffer) +{ + int retval; + uint32_t i; + + assert(jtag_info); + assert(jtag_info->tap); + + LOG_DEBUG("Reading %s registers: addr[0]=0x%" PRIx32 ";count=%" PRIu32, + (type == ARC_JTAG_CORE_REG ? "core" : "aux"), *addr, count); + + if (!count) { + LOG_ERROR("Trying to read 0 registers"); + return ERROR_FAIL; + } + + arc_jtag_enque_reset_transaction(jtag_info); + + /* What type of registers we are reading? */ + const uint32_t transaction = (type == ARC_JTAG_CORE_REG ? + ARC_JTAG_READ_FROM_CORE_REG : ARC_JTAG_READ_FROM_AUX_REG); + arc_jtag_enque_set_transaction(jtag_info, transaction, TAP_DRPAUSE); + + uint8_t *data_buf = calloc(sizeof(uint8_t), count * 4); + + arc_jtag_enque_register_rw(jtag_info, addr, data_buf, NULL, count); + + retval = jtag_execute_queue(); + if (retval != ERROR_OK) { + LOG_ERROR("Failed to execute jtag queue: %d", retval); + retval = ERROR_FAIL; + goto exit; + } + + /* Convert byte-buffers to host /presentation. */ + for (i = 0; i < count; i++) + buffer[i] = buf_get_u32(data_buf + 4 * i, 0, 32); + + LOG_DEBUG("Read from register: buf[0]=0x%" PRIx32, buffer[0]); + +exit: + free(data_buf); + + return retval; +} + + +/** Wrapper function to ease writing of one core register. */ +int arc_jtag_write_core_reg_one(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t value) +{ + return arc_jtag_write_core_reg(jtag_info, &addr, 1, &value); +} + +/** + * Write core registers. addr is an array of addresses, and those addresses can + * be in any order, though it is recommended that they are in sequential order + * where possible, as this reduces number of JTAG commands to transfer. + * + * @param jtag_info + * @param addr Array of registers numbers. + * @param count Amount of registers in arrays. + * @param values Array of register values. + */ +int arc_jtag_write_core_reg(struct arc_jtag *jtag_info, uint32_t *addr, + uint32_t count, const uint32_t *buffer) +{ + return arc_jtag_write_registers(jtag_info, ARC_JTAG_CORE_REG, addr, count, + buffer); +} + +/** Wrapper function to ease reading of one core register. */ +int arc_jtag_read_core_reg_one(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t *value) +{ + return arc_jtag_read_core_reg(jtag_info, &addr, 1, value); +} + +/** + * Read core registers. addr is an array of addresses, and those addresses can + * be in any order, though it is recommended that they are in sequential order + * where possible, as this reduces number of JTAG commands to transfer. + * + * @param jtag_info + * @param addr Array of core register numbers. + * @param count Amount of registers in arrays. + * @param values Array of register values. + */ +int arc_jtag_read_core_reg(struct arc_jtag *jtag_info, uint32_t *addr, + uint32_t count, uint32_t *buffer) +{ + return arc_jtag_read_registers(jtag_info, ARC_JTAG_CORE_REG, addr, count, + buffer); +} + +/** Wrapper function to ease writing of one AUX register. */ +int arc_jtag_write_aux_reg_one(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t value) +{ + return arc_jtag_write_aux_reg(jtag_info, &addr, 1, &value); +} + +/** + * Write AUX registers. addr is an array of addresses, and those addresses can + * be in any order, though it is recommended that they are in sequential order + * where possible, as this reduces number of JTAG commands to transfer. + * + * @param jtag_info + * @param addr Array of registers numbers. + * @param count Amount of registers in arrays. + * @param values Array of register values. + */ +int arc_jtag_write_aux_reg(struct arc_jtag *jtag_info, uint32_t *addr, + uint32_t count, const uint32_t *buffer) +{ + return arc_jtag_write_registers(jtag_info, ARC_JTAG_AUX_REG, addr, count, + buffer); +} + +/** Wrapper function to ease reading of one AUX register. */ +int arc_jtag_read_aux_reg_one(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t *value) +{ + return arc_jtag_read_aux_reg(jtag_info, &addr, 1, value); +} + +/** + * Read AUX registers. addr is an array of addresses, and those addresses can + * be in any order, though it is recommended that they are in sequential order + * where possible, as this reduces number of JTAG commands to transfer. + * + * @param jtag_info + * @param addr Array of AUX register numbers. + * @param count Amount of registers in arrays. + * @param values Array of register values. + */ +int arc_jtag_read_aux_reg(struct arc_jtag *jtag_info, uint32_t *addr, + uint32_t count, uint32_t *buffer) +{ + return arc_jtag_read_registers(jtag_info, ARC_JTAG_AUX_REG, addr, count, + buffer); +} + +/** + * Write a sequence of 4-byte words into target memory. + * + * We can write only 4byte words via JTAG, so any non-word writes should be + * handled at higher levels by read-modify-write. + * + * This function writes directly to the memory, leaving any caches (if there + * are any) in inconsistent state. It is responsibility of upper level to + * resolve this. + * + * @param jtag_info + * @param addr Address of first word to write into. + * @param count Amount of word to write. + * @param buffer Array to write into memory. + */ +int arc_jtag_write_memory(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t count, const uint32_t *buffer) +{ + assert(jtag_info); + assert(buffer); + + LOG_DEBUG("Writing to memory: addr=0x%08" PRIx32 ";count=%" PRIu32 ";buffer[0]=0x%08" PRIx32, + addr, count, *buffer); + + /* No need to waste time on useless operations. */ + if (!count) + return ERROR_OK; + + /* We do not know where we come from. */ + arc_jtag_enque_reset_transaction(jtag_info); + + /* We want to write to memory. */ + arc_jtag_enque_set_transaction(jtag_info, ARC_JTAG_WRITE_TO_MEMORY, TAP_DRPAUSE); + + /* Set target memory address of the first word. */ + arc_jtag_enque_write_ir(jtag_info, ARC_JTAG_ADDRESS_REG); + arc_jtag_enque_write_dr(jtag_info, addr, TAP_DRPAUSE); + + /* Start sending words. Address is auto-incremented on 4bytes by HW. */ + arc_jtag_enque_write_ir(jtag_info, ARC_JTAG_DATA_REG); + + uint32_t i; + for (i = 0; i < count; i++) + arc_jtag_enque_write_dr(jtag_info, *(buffer + i), TAP_IDLE); + + return jtag_execute_queue(); +} + +/** + * Read a sequence of 4-byte words from target memory. + * + * We can read only 4byte words via JTAG. + * + * This function read directly from the memory, so it can read invalid data if + * data cache hasn't been flushed before hand. It is responsibility of upper + * level to resolve this. + * + * @param jtag_info + * @param addr Address of first word to read from. + * @param count Amount of words to read. + * @param buffer Array of words to read into. + * @param slow_memory Whether this is a slow memory (DDR) or fast (CCM). + */ +int arc_jtag_read_memory(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t count, uint32_t *buffer, bool slow_memory) +{ + uint8_t *data_buf; + uint32_t i; + int retval = ERROR_OK; + + + assert(jtag_info); + assert(jtag_info->tap); + + LOG_DEBUG("Reading memory: addr=0x%" PRIx32 ";count=%" PRIu32 ";slow=%c", + addr, count, slow_memory ? 'Y' : 'N'); + + if (!count) + return ERROR_OK; + + data_buf = calloc(sizeof(uint8_t), count * 4); + arc_jtag_enque_reset_transaction(jtag_info); + + /* We are reading from memory. */ + arc_jtag_enque_set_transaction(jtag_info, ARC_JTAG_READ_FROM_MEMORY, TAP_DRPAUSE); + + /* Read data */ + for (i = 0; i < count; i++) { + /* When several words are read at consequent addresses we can + * rely on ARC JTAG auto-incrementing address. That means that + * address can be set only once, for a first word. However it + * has been noted that at least in some cases when reading from + * DDR, JTAG returns 0 instead of a real value. To workaround + * this issue we need to do totally non-required address + * writes, which however resolve a problem by introducing + * delay. See STAR 9000832538... */ + if (slow_memory || i == 0) { + /* Set address */ + arc_jtag_enque_write_ir(jtag_info, ARC_JTAG_ADDRESS_REG); + arc_jtag_enque_write_dr(jtag_info, addr + i * 4, TAP_IDLE); + + arc_jtag_enque_write_ir(jtag_info, ARC_JTAG_DATA_REG); + } + arc_jtag_enque_read_dr(jtag_info, data_buf + i * 4, TAP_IDLE); + } + retval = jtag_execute_queue(); + if (retval != ERROR_OK) { + LOG_ERROR("Failed to execute jtag queue: %d", retval); + retval = ERROR_FAIL; + goto exit; + } + + /* Convert byte-buffers to host presentation. */ + for (i = 0; i < count; i++) + buffer[i] = buf_get_u32(data_buf + 4*i, 0, 32); + +exit: + free(data_buf); + + return retval; +} + diff --git a/src/target/arc_jtag.h b/src/target/arc_jtag.h new file mode 100644 index 000000000..99795f56a --- /dev/null +++ b/src/target/arc_jtag.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * + * Frank Dols * + * Mischa Jonker * + * Anton Kolesov * + * Evgeniy Didin * + * * + * SPDX-License-Identifier: GPL-2.0-or-later * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_ARC_JTAG_H +#define OPENOCD_TARGET_ARC_JTAG_H + +#define ARC_TRANSACTION_CMD_REG 0x9 /* Command to perform */ +#define ARC_TRANSACTION_CMD_REG_LENGTH 4 + +/* Jtag status register, value is placed in IR to read jtag status register */ +#define ARC_JTAG_STATUS_REG 0x8 +#define ARC_JTAG_ADDRESS_REG 0xA /* SoC address to access */ +#define ARC_JTAG_DATA_REG 0xB /* Data read/written from SoC */ + +/* Jtag status register field */ +#define ARC_JTAG_STAT_RU 0x10 + +/* ARC Jtag transactions */ +#define ARC_JTAG_WRITE_TO_MEMORY 0x0 +#define ARC_JTAG_WRITE_TO_CORE_REG 0x1 +#define ARC_JTAG_WRITE_TO_AUX_REG 0x2 +#define ARC_JTAG_CMD_NOP 0x3 +#define ARC_JTAG_READ_FROM_MEMORY 0x4 +#define ARC_JTAG_READ_FROM_CORE_REG 0x5 +#define ARC_JTAG_READ_FROM_AUX_REG 0x6 + +#define ARC_JTAG_CORE_REG 0x0 +#define ARC_JTAG_AUX_REG 0x1 + + +struct arc_jtag { + struct jtag_tap *tap; + uint32_t cur_trans; +}; + +/* ----- Exported JTAG functions ------------------------------------------- */ + +int arc_jtag_startup(struct arc_jtag *jtag_info); +int arc_jtag_status(struct arc_jtag *const jtag_info, uint32_t *const value); + +int arc_jtag_write_core_reg(struct arc_jtag *jtag_info, uint32_t *addr, + uint32_t count, const uint32_t *buffer); +int arc_jtag_read_core_reg(struct arc_jtag *jtag_info, uint32_t *addr, + uint32_t count, uint32_t *buffer); +int arc_jtag_write_core_reg_one(struct arc_jtag *jtag_info, uint32_t addr, + const uint32_t buffer); +int arc_jtag_read_core_reg_one(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t *buffer); + +int arc_jtag_write_aux_reg(struct arc_jtag *jtag_info, uint32_t *addr, + uint32_t count, const uint32_t *buffer); +int arc_jtag_write_aux_reg_one(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t value); +int arc_jtag_read_aux_reg(struct arc_jtag *jtag_info, uint32_t *addr, + uint32_t count, uint32_t *buffer); +int arc_jtag_read_aux_reg_one(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t *value); + +int arc_jtag_write_memory(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t count, const uint32_t *buffer); +int arc_jtag_read_memory(struct arc_jtag *jtag_info, uint32_t addr, + uint32_t count, uint32_t *buffer, bool slow_memory); +#endif /* OPENOCD_TARGET_ARC_JTAG_H */ diff --git a/src/target/arc_mem.c b/src/target/arc_mem.c new file mode 100644 index 000000000..e80bfb4e4 --- /dev/null +++ b/src/target/arc_mem.c @@ -0,0 +1,287 @@ +/*************************************************************************** + * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * + * Frank Dols * + * Mischa Jonker * + * Anton Kolesov * + * Evgeniy Didin * + * * + * SPDX-License-Identifier: GPL-2.0-or-later * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arc.h" + +/* ----- Supporting functions ---------------------------------------------- */ +static bool arc_mem_is_slow_memory(struct arc_common *arc, uint32_t addr, + uint32_t size, uint32_t count) +{ + uint32_t addr_end = addr + size * count; + /* `_end` field can overflow - it points to the first byte after the end, + * therefore if DCCM is right at the end of memory address space, then + * dccm_end will be 0. */ + assert(addr_end >= addr || addr_end == 0); + + return !((addr >= arc->dccm_start && addr_end <= arc->dccm_end) || + (addr >= arc->iccm0_start && addr_end <= arc->iccm0_end) || + (addr >= arc->iccm1_start && addr_end <= arc->iccm1_end)); +} + +/* Write word at word-aligned address */ +static int arc_mem_write_block32(struct target *target, uint32_t addr, + uint32_t count, void *buf) +{ + struct arc_common *arc = target_to_arc(target); + + LOG_DEBUG("Write 4-byte memory block: addr=0x%08" PRIx32 ", count=%" PRIu32, + addr, count); + + /* Check arguments */ + assert(!(addr & 3)); + + /* No need to flush cache, because we don't read values from memory. */ + CHECK_RETVAL(arc_jtag_write_memory(&arc->jtag_info, addr, count, + (uint32_t *)buf)); + + return ERROR_OK; +} + +/* Write half-word at half-word-aligned address */ +static int arc_mem_write_block16(struct target *target, uint32_t addr, + uint32_t count, void *buf) +{ + struct arc_common *arc = target_to_arc(target); + uint32_t i; + uint32_t buffer_he; + uint8_t buffer_te[sizeof(uint32_t)]; + uint8_t halfword_te[sizeof(uint16_t)]; + + LOG_DEBUG("Write 2-byte memory block: addr=0x%08" PRIx32 ", count=%" PRIu32, + addr, count); + + /* Check arguments */ + assert(!(addr & 1)); + + /* non-word writes are less common, than 4-byte writes, so I suppose we can + * allowe ourselves to write this in a cycle, instead of calling arc_jtag + * with count > 1. */ + for (i = 0; i < count; i++) { + /* We can read only word at word-aligned address. Also *jtag_read_memory + * functions return data in host endianness, so host endianness != + * target endianness we have to convert data back to target endianness, + * or bytes will be at the wrong places.So: + * 1) read word + * 2) convert to target endianness + * 3) make changes + * 4) convert back to host endianness + * 5) write word back to target. + */ + bool is_slow_memory = arc_mem_is_slow_memory(arc, + (addr + i * sizeof(uint16_t)) & ~3u, 4, 1); + CHECK_RETVAL(arc_jtag_read_memory(&arc->jtag_info, + (addr + i * sizeof(uint16_t)) & ~3u, 1, &buffer_he, + is_slow_memory)); + target_buffer_set_u32(target, buffer_te, buffer_he); + + /* buf is in host endianness, convert to target */ + target_buffer_set_u16(target, halfword_te, ((uint16_t *)buf)[i]); + + memcpy(buffer_te + ((addr + i * sizeof(uint16_t)) & 3u), + halfword_te, sizeof(uint16_t)); + + buffer_he = target_buffer_get_u32(target, buffer_te); + + CHECK_RETVAL(arc_jtag_write_memory(&arc->jtag_info, + (addr + i * sizeof(uint16_t)) & ~3u, 1, &buffer_he)); + } + + return ERROR_OK; +} + +/* Write byte at address */ +static int arc_mem_write_block8(struct target *target, uint32_t addr, + uint32_t count, void *buf) +{ + struct arc_common *arc = target_to_arc(target); + uint32_t i; + uint32_t buffer_he; + uint8_t buffer_te[sizeof(uint32_t)]; + + + LOG_DEBUG("Write 1-byte memory block: addr=0x%08" PRIx32 ", count=%" PRIu32, + addr, count); + + /* non-word writes are less common, than 4-byte writes, so I suppose we can + * allowe ourselves to write this in a cycle, instead of calling arc_jtag + * with count > 1. */ + for (i = 0; i < count; i++) { + /* See comment in arc_mem_write_block16 for details. Since it is a byte + * there is not need to convert write buffer to target endianness, but + * we still have to convert read buffer. */ + CHECK_RETVAL(arc_jtag_read_memory(&arc->jtag_info, (addr + i) & ~3, 1, &buffer_he, + arc_mem_is_slow_memory(arc, (addr + i) & ~3, 4, 1))); + target_buffer_set_u32(target, buffer_te, buffer_he); + memcpy(buffer_te + ((addr + i) & 3), (uint8_t *)buf + i, 1); + buffer_he = target_buffer_get_u32(target, buffer_te); + CHECK_RETVAL(arc_jtag_write_memory(&arc->jtag_info, (addr + i) & ~3, 1, &buffer_he)); + } + + return ERROR_OK; +} + +/* ----- Exported functions ------------------------------------------------ */ +int arc_mem_write(struct target *target, target_addr_t address, uint32_t size, + uint32_t count, const uint8_t *buffer) +{ + int retval = ERROR_OK; + void *tunnel = NULL; + + LOG_DEBUG("address: 0x%08" TARGET_PRIxADDR ", size: %" PRIu32 ", count: %" PRIu32, + address, size, count); + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* sanitize arguments */ + if (((size != 4) && (size != 2) && (size != 1)) || !(count) || !(buffer)) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) + return ERROR_TARGET_UNALIGNED_ACCESS; + + /* correct endianess if we have word or hword access */ + if (size > 1) { + /* + * arc_..._write_mem with size 4/2 requires uint32_t/uint16_t + * in host endianness, but byte array represents target endianness. + */ + tunnel = calloc(1, count * size * sizeof(uint8_t)); + + if (!tunnel) { + LOG_ERROR("Unable to allocate memory"); + return ERROR_FAIL; + } + + switch (size) { + case 4: + target_buffer_get_u32_array(target, buffer, count, + (uint32_t *)tunnel); + break; + case 2: + target_buffer_get_u16_array(target, buffer, count, + (uint16_t *)tunnel); + break; + } + buffer = tunnel; + } + + if (size == 4) { + retval = arc_mem_write_block32(target, address, count, (void *)buffer); + } else if (size == 2) { + /* We convert buffer from host endianness to target. But then in + * write_block16, we do the reverse. Is there a way to avoid this without + * breaking other cases? */ + retval = arc_mem_write_block16(target, address, count, (void *)buffer); + } else { + retval = arc_mem_write_block8(target, address, count, (void *)buffer); + } + + free(tunnel); + + return retval; +} + +static int arc_mem_read_block(struct target *target, target_addr_t addr, + uint32_t size, uint32_t count, void *buf) +{ + struct arc_common *arc = target_to_arc(target); + + LOG_DEBUG("Read memory: addr=0x%08" TARGET_PRIxADDR ", size=%" PRIu32 + ", count=%" PRIu32, addr, size, count); + assert(!(addr & 3)); + assert(size == 4); + + CHECK_RETVAL(arc_jtag_read_memory(&arc->jtag_info, addr, count, buf, + arc_mem_is_slow_memory(arc, addr, size, count))); + + return ERROR_OK; +} + +int arc_mem_read(struct target *target, target_addr_t address, uint32_t size, + uint32_t count, uint8_t *buffer) +{ + int retval = ERROR_OK; + void *tunnel_he; + uint8_t *tunnel_te; + uint32_t words_to_read, bytes_to_read; + + + LOG_DEBUG("Read memory: addr=0x%08" TARGET_PRIxADDR ", size=%" PRIu32 + ", count=%" PRIu32, address, size, count); + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* Sanitize arguments */ + if (((size != 4) && (size != 2) && (size != 1)) || !(count) || !(buffer)) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) + return ERROR_TARGET_UNALIGNED_ACCESS; + + /* Reads are word-aligned, so padding might be required if count > 1. + * NB: +3 is a padding for the last word (in case it's not aligned; + * addr&3 is a padding for the first word (since address can be + * unaligned as well). */ + bytes_to_read = (count * size + 3 + (address & 3u)) & ~3u; + words_to_read = bytes_to_read >> 2; + tunnel_he = calloc(1, bytes_to_read); + tunnel_te = calloc(1, bytes_to_read); + + if (!tunnel_he || !tunnel_te) { + LOG_ERROR("Unable to allocate memory"); + free(tunnel_he); + free(tunnel_te); + return ERROR_FAIL; + } + + /* We can read only word-aligned words. */ + retval = arc_mem_read_block(target, address & ~3u, sizeof(uint32_t), + words_to_read, tunnel_he); + + /* arc_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */ + /* endianness, but byte array should represent target endianness */ + + if (ERROR_OK == retval) { + switch (size) { + case 4: + target_buffer_set_u32_array(target, buffer, count, + tunnel_he); + break; + case 2: + target_buffer_set_u32_array(target, tunnel_te, + words_to_read, tunnel_he); + /* Will that work properly with count > 1 and big endian? */ + memcpy(buffer, tunnel_te + (address & 3u), + count * sizeof(uint16_t)); + break; + case 1: + target_buffer_set_u32_array(target, tunnel_te, + words_to_read, tunnel_he); + /* Will that work properly with count > 1 and big endian? */ + memcpy(buffer, tunnel_te + (address & 3u), count); + break; + } + } + + free(tunnel_he); + free(tunnel_te); + + return retval; +} diff --git a/src/target/arc_mem.h b/src/target/arc_mem.h new file mode 100644 index 000000000..06e1c88d1 --- /dev/null +++ b/src/target/arc_mem.h @@ -0,0 +1,21 @@ +/*************************************************************************** + * Copyright (C) 2013-2014,2019-2020 Synopsys, Inc. * + * Frank Dols * + * Anton Kolesov * + * Evgeniy Didin * + * * + * SPDX-License-Identifier: GPL-2.0-or-later * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_ARC_MEM_H +#define OPENOCD_TARGET_ARC_MEM_H + +/* ----- Exported functions ------------------------------------------------ */ + +int arc_mem_read(struct target *target, target_addr_t address, uint32_t size, + uint32_t count, uint8_t *buffer); +int arc_mem_write(struct target *target, target_addr_t address, uint32_t size, + uint32_t count, const uint8_t *buffer); + + +#endif /* OPENOCD_TARGET_ARC_MEM_H */ diff --git a/src/target/target.c b/src/target/target.c index 688d31890..1ba4e0987 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -111,6 +111,7 @@ extern struct target_type stm8_target; extern struct target_type riscv_target; extern struct target_type mem_ap_target; extern struct target_type esirisc_target; +extern struct target_type arcv2_target; static struct target_type *target_types[] = { &arm7tdmi_target, @@ -146,6 +147,7 @@ static struct target_type *target_types[] = { &riscv_target, &mem_ap_target, &esirisc_target, + &arcv2_target, #if BUILD_TARGET64 &aarch64_target, &mips_mips64_target, From 39d54ee96973d3e54a8722112cb9ca25245d01ad Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Fri, 28 Feb 2020 11:14:42 +0300 Subject: [PATCH 156/354] target/arc: fix clang static analyzer warnings Fixes: * Removed typo in *bitfields initializations. * Removed potentional memory leak allocating reg_data_type_struct_field/reg_data_type_flags_field objects. * Initialize buffers with "0" before usage in buf_set_u32(). * Removed memory leak in jim_arc_add_reg(). Change-Id: Iefde57cd4a48c4f3350c376475df8642607f52ff Signed-off-by: Evgeniy Didin Reviewed-on: http://openocd.zylin.com/5480 Reviewed-by: Tomas Vanek Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/arc.c | 4 ++-- src/target/arc.h | 4 ++++ src/target/arc_cmd.c | 7 +++++-- src/target/arc_jtag.c | 6 +++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/target/arc.c b/src/target/arc.c index 45ef725dc..244dd5247 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -1241,11 +1241,11 @@ static void arc_deinit_target(struct target *target) /* Free arc-specific reg_data_types allocations*/ list_for_each_entry_safe_reverse(type, n, &arc->reg_data_types, list) { if (type->data_type.type_class == REG_TYPE_CLASS_STRUCT) { - free(type->data_type.reg_type_struct->fields); + free(type->reg_type_struct_field); free(type->bitfields); free(type); } else if (type->data_type.type_class == REG_TYPE_CLASS_FLAGS) { - free(type->data_type.reg_type_flags->fields); + free(type->reg_type_flags_field); free(type->bitfields); free(type); } diff --git a/src/target/arc.h b/src/target/arc.h index 311648e15..af4149f97 100644 --- a/src/target/arc.h +++ b/src/target/arc.h @@ -61,6 +61,10 @@ struct arc_reg_data_type { struct reg_data_type_struct data_type_struct; char data_type_id[REG_TYPE_MAX_NAME_LENGTH]; struct arc_reg_bitfield *bitfields; + union { + struct reg_data_type_struct_field *reg_type_struct_field; + struct reg_data_type_flags_field *reg_type_flags_field; + }; }; diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c index 3f6caf751..3475762f4 100644 --- a/src/target/arc_cmd.c +++ b/src/target/arc_cmd.c @@ -163,7 +163,8 @@ static int jim_arc_add_reg_type_flags(Jim_Interp *interp, int argc, struct arc_reg_data_type *type = calloc(1, sizeof(*type)); struct reg_data_type_flags *flags = &type->data_type_flags; struct reg_data_type_flags_field *fields = calloc(fields_sz, sizeof(*fields)); - struct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*type)); + type->reg_type_flags_field = fields; + struct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*bitfields)); if (!(type && fields && bitfields)) { Jim_SetResultFormatted(goi.interp, "Failed to allocate memory."); goto fail; @@ -528,7 +529,8 @@ static int jim_arc_add_reg_type_struct(Jim_Interp *interp, int argc, struct arc_reg_data_type *type = calloc(1, sizeof(*type)); struct reg_data_type_struct *struct_type = &type->data_type_struct; struct reg_data_type_struct_field *fields = calloc(fields_sz, sizeof(*fields)); - struct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*type)); + type->reg_type_struct_field = fields; + struct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*bitfields)); if (!(type && fields && bitfields)) { Jim_SetResultFormatted(goi.interp, "Failed to allocate memory."); goto fail; @@ -789,6 +791,7 @@ static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) target = get_current_target(ctx); if (!target) { Jim_SetResultFormatted(goi.interp, "No current target"); + free_reg_desc(reg); return JIM_ERR; } diff --git a/src/target/arc_jtag.c b/src/target/arc_jtag.c index dd800a462..274d61f3a 100644 --- a/src/target/arc_jtag.c +++ b/src/target/arc_jtag.c @@ -26,7 +26,7 @@ static void arc_jtag_enque_write_ir(struct arc_jtag *jtag_info, uint32_t { uint32_t current_instr; struct jtag_tap *tap; - uint8_t instr_buffer[sizeof(uint32_t)]; + uint8_t instr_buffer[sizeof(uint32_t)] = {0}; assert(jtag_info); assert(jtag_info->tap); @@ -90,7 +90,7 @@ static void arc_jtag_enque_read_dr(struct arc_jtag *jtag_info, uint8_t *data, static void arc_jtag_enque_write_dr(struct arc_jtag *jtag_info, uint32_t data, tap_state_t end_state) { - uint8_t out_value[sizeof(uint32_t)]; + uint8_t out_value[sizeof(uint32_t)] = {0}; assert(jtag_info); assert(jtag_info->tap); @@ -118,7 +118,7 @@ static void arc_jtag_enque_write_dr(struct arc_jtag *jtag_info, uint32_t data, static void arc_jtag_enque_set_transaction(struct arc_jtag *jtag_info, uint32_t new_trans, tap_state_t end_state) { - uint8_t out_value[sizeof(uint32_t)]; + uint8_t out_value[sizeof(uint32_t)] = {0}; assert(jtag_info); assert(jtag_info->tap); From 98ea23a7ff1e563e809111e3bc26f5bf90be0c5d Mon Sep 17 00:00:00 2001 From: Michael Stoll Date: Wed, 19 Feb 2020 17:32:26 +0100 Subject: [PATCH 157/354] Add support for SAMD21E17D device Change-Id: Id0a533f8899b20cc87e3a9143383ddf279c86301 Signed-off-by: Michael Stoll Reviewed-on: http://openocd.zylin.com/5458 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/at91samd.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c index b6cff9a67..6e89099ab 100644 --- a/src/flash/nor/at91samd.c +++ b/src/flash/nor/at91samd.c @@ -181,6 +181,23 @@ static const struct samd_part samd21_parts[] = { { 0x26, "SAMD21E16B", 64, 8 }, { 0x27, "SAMD21E15B", 32, 4 }, + /* SAMD21 D and L Variants (from Errata) + http://ww1.microchip.com/downloads/en/DeviceDoc/ + SAM-D21-Family-Silicon-Errata-and-DataSheet-Clarification-DS80000760D.pdf */ + { 0x55, "SAMD21E16BU", 64, 8 }, + { 0x56, "SAMD21E15BU", 32, 4 }, + { 0x57, "SAMD21G16L", 64, 8 }, + { 0x3E, "SAMD21E16L", 64, 8 }, + { 0x3F, "SAMD21E15L", 32, 4 }, + { 0x62, "SAMD21E16CU", 64, 8 }, + { 0x63, "SAMD21E15CU", 32, 4 }, + { 0x92, "SAMD21J17D", 128, 16 }, + { 0x93, "SAMD21G17D", 128, 16 }, + { 0x94, "SAMD21E17D", 128, 16 }, + { 0x95, "SAMD21E17DU", 128, 16 }, + { 0x96, "SAMD21G17L", 128, 16 }, + { 0x97, "SAMD21E17L", 128, 16 }, + /* Known SAMDA1 parts. SAMD-A1 series uses the same series identifier like the SAMD21 taken from http://ww1.microchip.com/downloads/en/DeviceDoc/40001895A.pdf (pages 14-17) */ From 0b7eca17691a16e79881243d6d0f38c3eaeb360d Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Fri, 7 Feb 2020 00:12:48 +0100 Subject: [PATCH 158/354] flash/stm32h7x: add support of STM32H7Ax/H7Bx devices this new device has the following features: - single core cortex-M7 - 2MB flash - dual bank - page size 8k - write protection grouped by 4 sectors - write block size 128 bits (16 bytes) the bit definition of FLASH_CR is different than STM32H74x, that's why we introduced a helper to compute the FLASH_CR value Change-Id: I4da10cde8dd215b1b0f2645f0efdba9d198038d1 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5441 Tested-by: jenkins Reviewed-by: Tomas Vanek --- contrib/loaders/flash/stm32/stm32h7x.S | 73 +++++---- contrib/loaders/flash/stm32/stm32h7x.inc | 13 +- src/flash/nor/stm32h7x.c | 182 +++++++++++++++-------- 3 files changed, 163 insertions(+), 105 deletions(-) diff --git a/contrib/loaders/flash/stm32/stm32h7x.S b/contrib/loaders/flash/stm32/stm32h7x.S index beb8fdbd4..a4317229e 100644 --- a/contrib/loaders/flash/stm32/stm32h7x.S +++ b/contrib/loaders/flash/stm32/stm32h7x.S @@ -25,29 +25,35 @@ * Code limitations: * The workarea must have size multiple of 4 bytes, since R/W * operations are all at 32 bits. - * The workarea must be big enough to contain 32 bytes of data, - * thus the minimum size is (rp, wp, data) = 4 + 4 + 32 = 40 bytes. + * The workarea must be big enough to contain rp, wp and data, thus the minumum + * workarea size is: min_wa_size = sizeof(rp, wp, data) = 4 + 4 + sizeof(data). + * - for 0x450 devices: sizeof(data) = 32 bytes, thus min_wa_size = 40 bytes. + * - for 0x480 devices: sizeof(data) = 16 bytes, thus min_wa_size = 24 bytes. * To benefit from concurrent host write-to-buffer and target * write-to-flash, the workarea must be way bigger than the minimum. - */ + * + * To avoid confusions the write word size is got from .block_size member of + * struct stm32h7x_part_info defined in stm32h7x.c +*/ /* * Params : * r0 = workarea start, status (out) * r1 = workarea end * r2 = target address - * r3 = count (256 bit words) - * r4 = flash reg base + * r3 = count (of write words) + * r4 = size of write word + * r5 = flash reg base * * Clobbered: - * r5 - rp - * r6 - wp, status, tmp - * r7 - loop index, tmp + * r6 - rp + * r7 - wp, status, tmp + * r8 - loop index, tmp */ #define STM32_FLASH_CR_OFFSET 0x0C /* offset of CR register in FLASH struct */ #define STM32_FLASH_SR_OFFSET 0x10 /* offset of SR register in FLASH struct */ -#define STM32_CR_PROG 0x00000032 /* PSIZE64 | PG */ +#define STM32_CR_PROG 0x00000002 /* PG */ #define STM32_SR_QW_MASK 0x00000004 /* QW */ #define STM32_SR_ERROR_MASK 0x07ee0000 /* DBECCERR | SNECCERR | RDSERR | RDPERR | OPERR | INCERR | STRBERR | PGSERR | WRPERR */ @@ -55,54 +61,55 @@ .thumb_func .global _start _start: - ldr r5, [r0, #4] /* read rp */ + ldr r6, [r0, #4] /* read rp */ wait_fifo: - ldr r6, [r0, #0] /* read wp */ - cbz r6, exit /* abort if wp == 0, status = 0 */ - subs r6, r6, r5 /* number of bytes available for read in r6 */ + ldr r7, [r0, #0] /* read wp */ + cbz r7, exit /* abort if wp == 0, status = 0 */ + subs r7, r7, r6 /* number of bytes available for read in r7 */ ittt mi /* if wrapped around */ - addmi r6, r1 /* add size of buffer */ - submi r6, r0 - submi r6, #8 - cmp r6, #32 /* wait until 32 bytes are available */ + addmi r7, r1 /* add size of buffer */ + submi r7, r0 + submi r7, #8 + cmp r7, r4 /* wait until data buffer is full */ bcc wait_fifo - mov r6, #STM32_CR_PROG - str r6, [r4, #STM32_FLASH_CR_OFFSET] + mov r7, #STM32_CR_PROG + str r7, [r5, #STM32_FLASH_CR_OFFSET] - mov r7, #8 /* program by 8 words = 32 bytes */ + mov r8, #4 + udiv r8, r4, r8 /* number of words is size of write word devided by 4*/ write_flash: dsb - ldr r6, [r5], #0x04 /* read one word from src, increment ptr */ - str r6, [r2], #0x04 /* write one word to dst, increment ptr */ + ldr r7, [r6], #0x04 /* read one word from src, increment ptr */ + str r7, [r2], #0x04 /* write one word to dst, increment ptr */ dsb - cmp r5, r1 /* if rp >= end of buffer ... */ + cmp r6, r1 /* if rp >= end of buffer ... */ it cs - addcs r5, r0, #8 /* ... then wrap at buffer start */ - subs r7, r7, #1 /* decrement loop index */ + addcs r6, r0, #8 /* ... then wrap at buffer start */ + subs r8, r8, #1 /* decrement loop index */ bne write_flash /* loop if not done */ busy: - ldr r6, [r4, #STM32_FLASH_SR_OFFSET] - tst r6, #STM32_SR_QW_MASK + ldr r7, [r5, #STM32_FLASH_SR_OFFSET] + tst r7, #STM32_SR_QW_MASK bne busy /* operation in progress, wait ... */ - ldr r7, =STM32_SR_ERROR_MASK - tst r6, r7 + ldr r8, =STM32_SR_ERROR_MASK + tst r7, r8 bne error /* fail... */ - str r5, [r0, #4] /* store rp */ + str r6, [r0, #4] /* store rp */ subs r3, r3, #1 /* decrement count */ bne wait_fifo /* loop if not done */ b exit error: - movs r7, #0 - str r7, [r0, #4] /* set rp = 0 on error */ + movs r8, #0 + str r8, [r0, #4] /* set rp = 0 on error */ exit: - mov r0, r6 /* return status in r0 */ + mov r0, r7 /* return status in r0 */ bkpt #0x00 .pool diff --git a/contrib/loaders/flash/stm32/stm32h7x.inc b/contrib/loaders/flash/stm32/stm32h7x.inc index ec14de0ef..015644ffa 100644 --- a/contrib/loaders/flash/stm32/stm32h7x.inc +++ b/contrib/loaders/flash/stm32/stm32h7x.inc @@ -1,7 +1,8 @@ /* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x45,0x68,0x06,0x68,0x36,0xb3,0x76,0x1b,0x42,0xbf,0x76,0x18,0x36,0x1a,0x08,0x3e, -0x20,0x2e,0xf6,0xd3,0x4f,0xf0,0x32,0x06,0xe6,0x60,0x4f,0xf0,0x08,0x07,0xbf,0xf3, -0x4f,0x8f,0x55,0xf8,0x04,0x6b,0x42,0xf8,0x04,0x6b,0xbf,0xf3,0x4f,0x8f,0x8d,0x42, -0x28,0xbf,0x00,0xf1,0x08,0x05,0x01,0x3f,0xf1,0xd1,0x26,0x69,0x16,0xf0,0x04,0x0f, -0xfb,0xd1,0x05,0x4f,0x3e,0x42,0x03,0xd1,0x45,0x60,0x01,0x3b,0xd9,0xd1,0x01,0xe0, -0x00,0x27,0x47,0x60,0x30,0x46,0x00,0xbe,0x00,0x00,0xee,0x07, +0x46,0x68,0x07,0x68,0x6f,0xb3,0xbf,0x1b,0x42,0xbf,0x7f,0x18,0x3f,0x1a,0x08,0x3f, +0xa7,0x42,0xf6,0xd3,0x4f,0xf0,0x02,0x07,0xef,0x60,0x4f,0xf0,0x04,0x08,0xb4,0xfb, +0xf8,0xf8,0xbf,0xf3,0x4f,0x8f,0x56,0xf8,0x04,0x7b,0x42,0xf8,0x04,0x7b,0xbf,0xf3, +0x4f,0x8f,0x8e,0x42,0x28,0xbf,0x00,0xf1,0x08,0x06,0xb8,0xf1,0x01,0x08,0xf0,0xd1, +0x2f,0x69,0x17,0xf0,0x04,0x0f,0xfb,0xd1,0xdf,0xf8,0x1c,0x80,0x17,0xea,0x08,0x0f, +0x03,0xd1,0x46,0x60,0x01,0x3b,0xd4,0xd1,0x03,0xe0,0x5f,0xf0,0x00,0x08,0xc0,0xf8, +0x04,0x80,0x38,0x46,0x00,0xbe,0x00,0x00,0x00,0x00,0xee,0x07, diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index d5b5daab2..7882c11a7 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -57,8 +57,6 @@ #define FLASH_FW (1 << 6) #define FLASH_START (1 << 7) -#define FLASH_SNB(a) ((a) << 8) - /* FLASH_SR register bits */ #define FLASH_BSY (1 << 0) /* Operation in progress */ #define FLASH_QW (1 << 2) /* Operation queue in progress */ @@ -101,25 +99,31 @@ #define FLASH_BANK1_ADDRESS 0x08100000 #define FLASH_REG_BASE_B0 0x52002000 #define FLASH_REG_BASE_B1 0x52002100 -#define FLASH_SIZE_ADDRESS 0x1FF1E880 -#define FLASH_BLOCK_SIZE 32 struct stm32h7x_rev { uint16_t rev; const char *str; }; +/* stm32h7x_part_info permits the store each device information and specificities. + * the default unit is byte unless the suffix '_kb' is used. */ + struct stm32h7x_part_info { uint16_t id; const char *device_str; const struct stm32h7x_rev *revs; size_t num_revs; - unsigned int page_size; + unsigned int page_size_kb; + unsigned int block_size; /* flash write word size in bytes */ uint16_t max_flash_size_kb; uint8_t has_dual_bank; uint16_t first_bank_size_kb; /* Used when has_dual_bank is true */ uint32_t flash_regs_base; /* Flash controller registers location */ uint32_t fsize_addr; /* Location of FSIZE register */ + uint32_t wps_group_size; /* write protection group sectors' count */ + uint32_t wps_mask; + /* function to compute flash_cr register values */ + uint32_t (*compute_flash_cr)(uint32_t cmd, int snb); }; struct stm32h7x_flash_bank { @@ -140,18 +144,58 @@ static const struct stm32h7x_rev stm32_450_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X" }, { 0x2003, "V" }, }; +static const struct stm32h7x_rev stm32_480_revs[] = { + { 0x1000, "A"}, +}; + +static uint32_t stm32x_compute_flash_cr_450(uint32_t cmd, int snb) +{ + return cmd | (snb << 8); +} + +static uint32_t stm32x_compute_flash_cr_480(uint32_t cmd, int snb) +{ + /* save FW and START bits, to be right shifted by 2 bits later */ + const uint32_t tmp = cmd & (FLASH_FW | FLASH_START); + + /* mask parallelism (ignored), FW and START bits */ + cmd &= ~(FLASH_PSIZE_64 | FLASH_FW | FLASH_START); + + return cmd | (tmp >> 2) | (snb << 6); +} + static const struct stm32h7x_part_info stm32h7x_parts[] = { { .id = 0x450, .revs = stm32_450_revs, .num_revs = ARRAY_SIZE(stm32_450_revs), .device_str = "STM32H74x/75x", - .page_size = 128, /* 128 KB */ + .page_size_kb = 128, + .block_size = 32, .max_flash_size_kb = 2048, .first_bank_size_kb = 1024, .has_dual_bank = 1, .flash_regs_base = FLASH_REG_BASE_B0, - .fsize_addr = FLASH_SIZE_ADDRESS, + .fsize_addr = 0x1FF1E880, + .wps_group_size = 1, + .wps_mask = 0xFF, + .compute_flash_cr = stm32x_compute_flash_cr_450, + }, + { + .id = 0x480, + .revs = stm32_480_revs, + .num_revs = ARRAY_SIZE(stm32_480_revs), + .device_str = "STM32H7Ax/7Bx", + .page_size_kb = 8, + .block_size = 16, + .max_flash_size_kb = 2048, + .first_bank_size_kb = 1024, + .has_dual_bank = 1, + .flash_regs_base = FLASH_REG_BASE_B0, + .fsize_addr = 0x08FFF80C, + .wps_group_size = 4, + .wps_mask = 0xFFFFFFFF, + .compute_flash_cr = stm32x_compute_flash_cr_480, }, }; @@ -170,9 +214,6 @@ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) stm32x_info->probed = false; stm32x_info->user_bank_size = bank->size; - bank->write_start_alignment = FLASH_BLOCK_SIZE; - bank->write_end_alignment = FLASH_BLOCK_SIZE; - return ERROR_OK; } @@ -403,14 +444,15 @@ static int stm32x_protect_check(struct flash_bank *bank) return retval; } - for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].is_protected = protection & (1 << i) ? 0 : 1; - } + for (int i = 0; i < bank->num_prot_blocks; i++) + bank->prot_blocks[i].is_protected = protection & (1 << i) ? 0 : 1; + return ERROR_OK; } static int stm32x_erase(struct flash_bank *bank, int first, int last) { + struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; int retval, retval2; assert(first < bank->num_sectors); @@ -436,13 +478,13 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last) for (int i = first; i <= last; i++) { LOG_DEBUG("erase sector %d", i); retval = stm32x_write_flash_reg(bank, FLASH_CR, - FLASH_SER | FLASH_SNB(i) | FLASH_PSIZE_64); + stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64, i)); if (retval != ERROR_OK) { LOG_ERROR("Error erase sector %d", i); goto flash_lock; } retval = stm32x_write_flash_reg(bank, FLASH_CR, - FLASH_SER | FLASH_SNB(i) | FLASH_PSIZE_64 | FLASH_START); + stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64 | FLASH_START, i)); if (retval != ERROR_OK) { LOG_ERROR("Error erase sector %d", i); goto flash_lock; @@ -501,18 +543,18 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct target *target = bank->target; + struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; /* - * If the size of the data part of the buffer is not a multiple of FLASH_BLOCK_SIZE, we get + * If the size of the data part of the buffer is not a multiple of .block_size, we get * "corrupted fifo read" pointer in target_run_flash_async_algorithm() */ - uint32_t data_size = 512 * FLASH_BLOCK_SIZE; /* 16384 */ + uint32_t data_size = 512 * stm32x_info->part_info->block_size; uint32_t buffer_size = 8 + data_size; struct working_area *write_algorithm; struct working_area *source; uint32_t address = bank->base + offset; - struct reg_param reg_params[5]; + struct reg_param reg_params[6]; struct armv7m_algorithm armv7m_info; - struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; int retval = ERROR_OK; static const uint8_t stm32x_flash_write_code[] = { @@ -555,21 +597,23 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */ init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */ init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */ - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (word-256 bits) */ - init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* flash reg base */ + init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count of words (word size = .block_size (bytes) */ + init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* word size in bytes */ + init_reg_param(®_params[5], "r5", 32, PARAM_OUT); /* flash reg base */ buf_set_u32(reg_params[0].value, 0, 32, source->address); buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); buf_set_u32(reg_params[2].value, 0, 32, address); buf_set_u32(reg_params[3].value, 0, 32, count); - buf_set_u32(reg_params[4].value, 0, 32, stm32x_info->flash_regs_base); + buf_set_u32(reg_params[4].value, 0, 32, stm32x_info->part_info->block_size); + buf_set_u32(reg_params[5].value, 0, 32, stm32x_info->flash_regs_base); retval = target_run_flash_async_algorithm(target, buffer, count, - FLASH_BLOCK_SIZE, + stm32x_info->part_info->block_size, 0, NULL, - 5, reg_params, + ARRAY_SIZE(reg_params), reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info); @@ -598,6 +642,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer, destroy_reg_param(®_params[2]); destroy_reg_param(®_params[3]); destroy_reg_param(®_params[4]); + destroy_reg_param(®_params[5]); return retval; } @@ -605,6 +650,7 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct target *target = bank->target; + struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; uint32_t address = bank->base + offset; int retval, retval2; @@ -614,18 +660,18 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, } /* should be enforced via bank->write_start_alignment */ - assert(!(offset % FLASH_BLOCK_SIZE)); + assert(!(offset % stm32x_info->part_info->block_size)); /* should be enforced via bank->write_end_alignment */ - assert(!(count % FLASH_BLOCK_SIZE)); + assert(!(count % stm32x_info->part_info->block_size)); retval = stm32x_unlock_reg(bank); if (retval != ERROR_OK) goto flash_lock; - uint32_t blocks_remaining = count / FLASH_BLOCK_SIZE; + uint32_t blocks_remaining = count / stm32x_info->part_info->block_size; - /* multiple words (32-bytes) to be programmed in block */ + /* multiple words (n * .block_size) to be programmed in block */ if (blocks_remaining) { retval = stm32x_write_block(bank, buffer, offset, blocks_remaining); if (retval != ERROR_OK) { @@ -635,8 +681,8 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, LOG_WARNING("couldn't use block writes, falling back to single memory accesses"); } } else { - buffer += blocks_remaining * FLASH_BLOCK_SIZE; - address += blocks_remaining * FLASH_BLOCK_SIZE; + buffer += blocks_remaining * stm32x_info->part_info->block_size; + address += blocks_remaining * stm32x_info->part_info->block_size; blocks_remaining = 0; } if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE)) @@ -653,11 +699,12 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, 4. Wait for flash operations completion */ while (blocks_remaining > 0) { - retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_PG | FLASH_PSIZE_64); + retval = stm32x_write_flash_reg(bank, FLASH_CR, + stm32x_info->part_info->compute_flash_cr(FLASH_PG | FLASH_PSIZE_64, 0)); if (retval != ERROR_OK) goto flash_lock; - retval = target_write_buffer(target, address, FLASH_BLOCK_SIZE, buffer); + retval = target_write_buffer(target, address, stm32x_info->part_info->block_size, buffer); if (retval != ERROR_OK) goto flash_lock; @@ -665,8 +712,8 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, if (retval != ERROR_OK) goto flash_lock; - buffer += FLASH_BLOCK_SIZE; - address += FLASH_BLOCK_SIZE; + buffer += stm32x_info->part_info->block_size; + address += stm32x_info->part_info->block_size; blocks_remaining--; } @@ -678,16 +725,6 @@ flash_lock: return (retval == ERROR_OK) ? retval2 : retval; } -static void setup_sector(struct flash_bank *bank, int start, int num, int size) -{ - for (int i = start; i < (start + num) ; i++) { - assert(i < bank->num_sectors); - bank->sectors[i].offset = bank->size; - bank->sectors[i].size = size; - bank->size += bank->sectors[i].size; - } -} - static int stm32x_read_id_code(struct flash_bank *bank, uint32_t *id) { /* read stm32 device id register */ @@ -779,35 +816,45 @@ static int stm32x_probe(struct flash_bank *bank) /* did we assign flash size? */ assert(flash_size_in_kb != 0xffff); - /* calculate numbers of pages */ - int num_pages = flash_size_in_kb / stm32x_info->part_info->page_size; - - /* check that calculation result makes sense */ - assert(num_pages > 0); - - if (bank->sectors) { - free(bank->sectors); - bank->sectors = NULL; - } - bank->base = base_address; - bank->num_sectors = num_pages; - bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); + bank->size = flash_size_in_kb * 1024; + bank->write_start_alignment = stm32x_info->part_info->block_size; + bank->write_end_alignment = stm32x_info->part_info->block_size; + + /* setup sectors */ + bank->num_sectors = flash_size_in_kb / stm32x_info->part_info->page_size_kb; + assert(bank->num_sectors > 0); + + if (bank->sectors) + free(bank->sectors); + + bank->sectors = alloc_block_array(0, stm32x_info->part_info->page_size_kb * 1024, + bank->num_sectors); + if (bank->sectors == NULL) { LOG_ERROR("failed to allocate bank sectors"); return ERROR_FAIL; } - bank->size = 0; - /* fixed memory */ - setup_sector(bank, 0, num_pages, stm32x_info->part_info->page_size * 1024); + /* setup protection blocks */ + const uint32_t wpsn = stm32x_info->part_info->wps_group_size; + assert(bank->num_sectors % wpsn == 0); - for (int i = 0; i < num_pages; i++) { - bank->sectors[i].is_erased = -1; - bank->sectors[i].is_protected = 0; + bank->num_prot_blocks = bank->num_sectors / wpsn; + assert(bank->num_prot_blocks > 0); + + if (bank->prot_blocks) + free(bank->prot_blocks); + + bank->prot_blocks = alloc_block_array(0, stm32x_info->part_info->page_size_kb * wpsn * 1024, + bank->num_prot_blocks); + + if (bank->prot_blocks == NULL) { + LOG_ERROR("failed to allocate bank prot_block"); + return ERROR_FAIL; } - stm32x_info->probed = true; + stm32x_info->probed = 1; return ERROR_OK; } @@ -946,6 +993,7 @@ static int stm32x_mass_erase(struct flash_bank *bank) { int retval, retval2; struct target *target = bank->target; + struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -957,11 +1005,13 @@ static int stm32x_mass_erase(struct flash_bank *bank) goto flash_lock; /* mass erase flash memory bank */ - retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_BER | FLASH_PSIZE_64); + retval = stm32x_write_flash_reg(bank, FLASH_CR, + stm32x_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64, 0)); if (retval != ERROR_OK) goto flash_lock; - retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_BER | FLASH_PSIZE_64 | FLASH_START); + retval = stm32x_write_flash_reg(bank, FLASH_CR, + stm32x_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64 | FLASH_START, 0)); if (retval != ERROR_OK) goto flash_lock; From d55bcde16c54bbc76f5b670c076ce6c24a34faaa Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 6 Feb 2020 12:17:13 +0100 Subject: [PATCH 159/354] tcl/target: Abort on invalid SoC selection on R-Car Gen3 Instead of printing error message and continue, abort on invalid SoC selection right away. Change-Id: I9c7a7111b590c6c49a0826562380b881a162a8dc Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5439 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/target/renesas_rcar_gen3.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcl/target/renesas_rcar_gen3.cfg b/tcl/target/renesas_rcar_gen3.cfg index 2c478b268..34c191827 100644 --- a/tcl/target/renesas_rcar_gen3.cfg +++ b/tcl/target/renesas_rcar_gen3.cfg @@ -76,7 +76,7 @@ switch $_soc { set _boot_core CA53 } default { - echo "'$_soc' is invalid!" + error "'$_soc' is invalid!" } } From 3a8bffbef6afb4b7349d6340c9bae6789c05a3d3 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 7 Jan 2020 22:49:45 +0100 Subject: [PATCH 160/354] tcl/target: Add unified config for Renesas R-Car Gen2 targets Add configuration for the Renesas R-Car Generation 2 targets. These are SoCs with Cortex A15s and A7s. All cores currently supported by OpenOCD are supported here as well as two new cores, M2N and V2H, for the sake of support completeness. Change-Id: Ib6fe70a91360b4f8bd69822ee28b6dea530cfa0a Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5397 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/target/renesas_rcar_gen2.cfg | 123 +++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 tcl/target/renesas_rcar_gen2.cfg diff --git a/tcl/target/renesas_rcar_gen2.cfg b/tcl/target/renesas_rcar_gen2.cfg new file mode 100644 index 000000000..9f7421d91 --- /dev/null +++ b/tcl/target/renesas_rcar_gen2.cfg @@ -0,0 +1,123 @@ +# Renesas R-Car Generation 2 SOCs +# - There are a combination of Cortex-A15s and Cortex-A7s for each Gen2 SOC +# - Each SOC can boot through any of the, up to 2, core types that it has +# e.g. H2 can boot through Cortex-A15 or Cortex-A7 + +# Supported Gen2 SOCs and their cores: +# H2: Cortex-A15 x 4, Cortex-A7 x 4 +# M2: Cortex-A15 x 2 +# V2H: Cortex-A15 x 2 +# M2N: Cortex-A15 x 2 +# E2: Cortex-A7 x 2 + +# Usage: +# There are 2 configuration options: +# SOC: Selects the supported SOC. (Default 'H2') +# BOOT_CORE: Selects the booting core. 'CA15', or 'CA7' +# Defaults to 'CA15' if the SOC has one, else defaults to 'CA7' + +if { [info exists SOC] } { + set _soc $SOC +} else { + set _soc H2 +} + +# Set configuration for each SOC and the default 'BOOT_CORE' +switch $_soc { + H2 { + set _CHIPNAME r8a7790 + set _num_ca15 4 + set _num_ca7 4 + set _boot_core CA15 + } + M2 { + set _CHIPNAME r8a7791 + set _num_ca15 2 + set _num_ca7 0 + set _boot_core CA15 + } + V2H { + set _CHIPNAME r8a7792 + set _num_ca15 2 + set _num_ca7 0 + set _boot_core CA15 + } + M2N { + set _CHIPNAME r8a7793 + set _num_ca15 2 + set _num_ca7 0 + set _boot_core CA15 + } + E2 { + set _CHIPNAME r8a7794 + set _num_ca15 0 + set _num_ca7 2 + set _boot_core CA7 + } + default { + error "'$_soc' is invalid!" + } +} + +# If configured, override the default 'CHIPNAME' +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} + +# If configured, override the default 'BOOT_CORE' +if { [info exists BOOT_CORE] } { + set _boot_core $BOOT_CORE +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + set _DAP_TAPID 0x4ba00477 +} + +echo "\t$_soc - $_num_ca15 CA15(s), $_num_ca7 CA7(s)" +echo "\tBoot Core - $_boot_core\n" + +set _DAPNAME $_CHIPNAME.dap + +# TAP and DAP +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID +dap create $_DAPNAME -chain-position $_CHIPNAME.cpu + +set CA15_DBGBASE {0x800B0000 0x800B2000 0x800B4000 0x800B6000} +set CA7_DBGBASE {0x800F0000 0x800F2000 0x800F4000 0x800F6000} + +set smp_targets "" + +proc setup_ca {core_name dbgbase num boot} { + global _CHIPNAME + global _DAPNAME + global smp_targets + for { set _core 0 } { $_core < $num } { incr _core } { + set _TARGETNAME $_CHIPNAME.$core_name.$_core + set _CTINAME $_TARGETNAME.cti + set _command "target create $_TARGETNAME cortex_a -dap $_DAPNAME \ + -coreid $_core -dbgbase [lindex $dbgbase $_core]" + if { $_core == 0 && $boot == 1 } { + set _targets "$_TARGETNAME" + } else { + set _command "$_command -defer-examine" + } + set smp_targets "$smp_targets $_TARGETNAME" + eval $_command + } +} + +# Organize target list based on the boot core +if { [string equal $_boot_core CA15] } { + setup_ca a15 $CA15_DBGBASE $_num_ca15 1 + setup_ca a7 $CA7_DBGBASE $_num_ca7 0 +} elseif { [string equal $_boot_core CA7] } { + setup_ca a7 $CA7_DBGBASE $_num_ca7 1 + setup_ca a15 $CA15_DBGBASE $_num_ca15 0 +} else { + setup_ca a15 $CA15_DBGBASE $_num_ca15 0 + setup_ca a7 $CA7_DBGBASE $_num_ca7 0 +} + +eval "target smp $smp_targets" From a01474bb4c4c43a2d10781668efa26e6774364ed Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 7 Jan 2020 22:54:32 +0100 Subject: [PATCH 161/354] tcl/target: Switch Renesas R-Car Gen2 boards to new config Switch Renesas R-Car Gen2 boards which are currently supported from the old ad-hoc SoC configuration to the new unified configuration. Change-Id: I8a67bceb3ae92d840ae4dbac20868c75e83f7d58 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5398 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/board/renesas_porter.cfg | 3 ++- tcl/board/renesas_silk.cfg | 3 ++- tcl/board/renesas_stout.cfg | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tcl/board/renesas_porter.cfg b/tcl/board/renesas_porter.cfg index c8032f512..b5622e683 100644 --- a/tcl/board/renesas_porter.cfg +++ b/tcl/board/renesas_porter.cfg @@ -1,4 +1,5 @@ # Renesas R-Car M2 Evaluation Board -source [find target/renesas_r8a7791.cfg] +set SOC M2 +source [find target/renesas_rcar_gen2.cfg] source [find board/renesas_gen2_common.cfg] diff --git a/tcl/board/renesas_silk.cfg b/tcl/board/renesas_silk.cfg index a026537d4..36af47ff4 100644 --- a/tcl/board/renesas_silk.cfg +++ b/tcl/board/renesas_silk.cfg @@ -1,4 +1,5 @@ # Renesas R-Car E2 Evaluation Board -source [find target/renesas_r8a7794.cfg] +set SOC E2 +source [find target/renesas_rcar_gen2.cfg] source [find board/renesas_gen2_common.cfg] diff --git a/tcl/board/renesas_stout.cfg b/tcl/board/renesas_stout.cfg index d35f8744f..7a8001796 100644 --- a/tcl/board/renesas_stout.cfg +++ b/tcl/board/renesas_stout.cfg @@ -1,4 +1,5 @@ # Renesas R-Car H2 Evaluation Board -source [find target/renesas_r8a7790.cfg] +set SOC H2 +source [find target/renesas_rcar_gen2.cfg] source [find board/renesas_gen2_common.cfg] From 8abe91cff960709ffd3ebbb9eb1dcf710dd83c1f Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Mon, 3 Feb 2020 19:44:40 +0100 Subject: [PATCH 162/354] remove libusb0_common support Supporting two libusb versions provides additional development challenges without additional advantage. In most cases we need to patch libusb0_common and libusb1_common without real ability to test libusb0_common. Change-Id: Icbb19c6809b14533fe2acf7a877377b3be4cbd61 Signed-off-by: Oleksij Rempel Reviewed-on: http://openocd.zylin.com/5432 Tested-by: jenkins --- configure.ac | 10 +- src/jtag/drivers/Makefile.am | 4 - src/jtag/drivers/libusb0_common.c | 230 ------------------------------ src/jtag/drivers/libusb0_common.h | 74 ---------- src/jtag/drivers/libusb_common.h | 2 - 5 files changed, 3 insertions(+), 317 deletions(-) delete mode 100644 src/jtag/drivers/libusb0_common.c delete mode 100644 src/jtag/drivers/libusb0_common.h diff --git a/configure.ac b/configure.ac index e87959c04..497b15fd1 100644 --- a/configure.ac +++ b/configure.ac @@ -116,10 +116,8 @@ m4_define([USB1_ADAPTERS], [[usb_blaster_2], [Altera USB-Blaster II Compatible], [USB_BLASTER_2]], [[ft232r], [Bitbang mode of FT232R based devices], [FT232R]], [[vsllink], [Versaloon-Link JTAG Programmer], [VSLLINK]], - [[xds110], [TI XDS110 Debug Probe], [XDS110]]]) - -m4_define([USB_ADAPTERS], - [[[osbdm], [OSBDM (JTAG only) Programmer], [OSBDM]], + [[xds110], [TI XDS110 Debug Probe], [XDS110]], + [[osbdm], [OSBDM (JTAG only) Programmer], [OSBDM]], [[opendous], [eStick/opendous JTAG Programmer], [OPENDOUS]], [[aice], [Andes JTAG Programmer], [AICE]]]) @@ -235,7 +233,6 @@ m4_define([AC_ARG_ADAPTERS], [ AC_ARG_ADAPTERS([ USB1_ADAPTERS, - USB_ADAPTERS, USB0_ADAPTERS, HIDAPI_ADAPTERS, HIDAPI_USB1_ADAPTERS, @@ -665,7 +662,6 @@ m4_define([PROCESS_ADAPTERS], [ ]) PROCESS_ADAPTERS([USB1_ADAPTERS], ["x$use_libusb1" = "xyes"], [libusb-1.x]) -PROCESS_ADAPTERS([USB_ADAPTERS], ["x$use_libusb1" = "xyes" -o "x$use_libusb0" = "xyes"], [libusb-1.x or libusb-0.1]) PROCESS_ADAPTERS([USB0_ADAPTERS], ["x$use_libusb0" = "xyes"], [libusb-0.1]) PROCESS_ADAPTERS([HIDAPI_ADAPTERS], ["x$use_hidapi" = "xyes"], [hidapi]) PROCESS_ADAPTERS([HIDAPI_USB1_ADAPTERS], ["x$use_hidapi" = "xyes" -a "x$use_libusb1" = "xyes"], [hidapi and libusb-1.x]) @@ -800,7 +796,7 @@ echo echo echo OpenOCD configuration summary echo -------------------------------------------------- -m4_foreach([adapter], [USB1_ADAPTERS, USB_ADAPTERS, USB0_ADAPTERS, +m4_foreach([adapter], [USB1_ADAPTERS, USB0_ADAPTERS, HIDAPI_ADAPTERS, HIDAPI_USB1_ADAPTERS, LIBFTDI_ADAPTERS, LIBJAYLINK_ADAPTERS, PCIE_ADAPTERS], [s=m4_format(["%-40s"], ADAPTER_DESC([adapter])) diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index 7fbcd584f..47b19470e 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -31,9 +31,6 @@ if USE_LIBUSB0 DRIVERFILES += %D%/usb_common.c %C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBUSB0_CFLAGS) %C%_libocdjtagdrivers_la_LIBADD += $(LIBUSB0_LIBS) -if !USE_LIBUSB1 -DRIVERFILES += %D%/libusb0_common.c -endif endif if USE_LIBFTDI @@ -171,7 +168,6 @@ DRIVERHEADERS = \ %D%/bitbang.h \ %D%/bitq.h \ %D%/jtag_usb_common.h \ - %D%/libusb0_common.h \ %D%/libusb1_common.h \ %D%/libusb_common.h \ %D%/minidriver_imp.h \ diff --git a/src/jtag/drivers/libusb0_common.c b/src/jtag/drivers/libusb0_common.c deleted file mode 100644 index 0e7858911..000000000 --- a/src/jtag/drivers/libusb0_common.c +++ /dev/null @@ -1,230 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * Copyright (C) 2011 by Mauro Gamba * - * * - * 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 * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "log.h" -#include "libusb0_common.h" - -static int jtag_libusb_error(int err) -{ - switch (err) { - case 0: - return ERROR_OK; - case -ETIMEDOUT: - return ERROR_TIMEOUT_REACHED; - default: - return ERROR_FAIL; - } -} - -static bool jtag_libusb_match(struct jtag_libusb_device *dev, - const uint16_t vids[], const uint16_t pids[]) -{ - for (unsigned i = 0; vids[i]; i++) { - if (dev->descriptor.idVendor == vids[i] && - dev->descriptor.idProduct == pids[i]) { - return true; - } - } - return false; -} - -/* Returns true if the string descriptor indexed by str_index in device matches string */ -static bool string_descriptor_equal(usb_dev_handle *device, uint8_t str_index, - const char *string) -{ - int retval; - bool matched; - char desc_string[256+1]; /* Max size of string descriptor */ - - if (str_index == 0) - return false; - - retval = usb_get_string_simple(device, str_index, - desc_string, sizeof(desc_string)-1); - if (retval < 0) { - LOG_ERROR("usb_get_string_simple() failed with %d", retval); - return false; - } - - /* Null terminate descriptor string in case it needs to be logged. */ - desc_string[sizeof(desc_string)-1] = '\0'; - - matched = strncmp(string, desc_string, sizeof(desc_string)) == 0; - if (!matched) - LOG_DEBUG("Device serial number '%s' doesn't match requested serial '%s'", - desc_string, string); - return matched; -} - -int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, - struct jtag_libusb_device_handle **out) -{ - int retval = ERROR_FAIL; - bool serial_mismatch = false; - struct jtag_libusb_device_handle *libusb_handle; - usb_init(); - - usb_find_busses(); - usb_find_devices(); - - struct usb_bus *busses = usb_get_busses(); - for (struct usb_bus *bus = busses; bus; bus = bus->next) { - for (struct usb_device *dev = bus->devices; - dev; dev = dev->next) { - if (!jtag_libusb_match(dev, vids, pids)) - continue; - - libusb_handle = usb_open(dev); - if (NULL == libusb_handle) { - LOG_ERROR("usb_open() failed with %s", usb_strerror()); - continue; - } - - /* Device must be open to use libusb_get_string_descriptor_ascii. */ - if (serial != NULL && - !string_descriptor_equal(libusb_handle, dev->descriptor.iSerialNumber, serial)) { - serial_mismatch = true; - usb_close(libusb_handle); - continue; - } - *out = libusb_handle; - retval = ERROR_OK; - serial_mismatch = false; - break; - } - } - - if (serial_mismatch) - LOG_INFO("No device matches the serial string"); - - return retval; -} - -void jtag_libusb_close(jtag_libusb_device_handle *dev) -{ - /* Close device */ - usb_close(dev); -} - -int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t requestType, - uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, - uint16_t size, unsigned int timeout) -{ - int transferred = 0; - - transferred = usb_control_msg(dev, requestType, request, wValue, wIndex, - bytes, size, timeout); - - if (transferred < 0) - transferred = 0; - - return transferred; -} - -int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout, int *transferred) -{ - int ret; - - *transferred = 0; - - ret = usb_bulk_write(dev, ep, bytes, size, timeout); - - if (ret < 0) { - LOG_ERROR("usb_bulk_write error: %i", ret); - return jtag_libusb_error(ret); - } - - return ERROR_OK; -} - -int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout, int *transferred) -{ - int ret; - - *transferred = 0; - - ret = usb_bulk_read(dev, ep, bytes, size, timeout); - - if (ret < 0) { - LOG_ERROR("usb_bulk_read error: %i", ret); - return jtag_libusb_error(ret); - } - - return ERROR_OK; -} - -int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, - int configuration) -{ - struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); - - return usb_set_configuration(devh, - udev->config[configuration].bConfigurationValue); -} - -int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, - unsigned int *usb_read_ep, - unsigned int *usb_write_ep, - int bclass, int subclass, int protocol, int trans_type) -{ - struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); - struct usb_interface *iface = udev->config->interface; - struct usb_interface_descriptor *desc = iface->altsetting; - - *usb_read_ep = *usb_write_ep = 0; - - for (int i = 0; i < desc->bNumEndpoints; i++) { - if ((bclass > 0 && desc->bInterfaceClass != bclass) || - (subclass > 0 && desc->bInterfaceSubClass != subclass) || - (protocol > 0 && desc->bInterfaceProtocol != protocol) || - (trans_type > 0 && (desc->endpoint[i].bmAttributes & 0x3) != trans_type)) - continue; - - uint8_t epnum = desc->endpoint[i].bEndpointAddress; - bool is_input = epnum & 0x80; - LOG_DEBUG("usb ep %s %02x", is_input ? "in" : "out", epnum); - if (is_input) - *usb_read_ep = epnum; - else - *usb_write_ep = epnum; - - if (*usb_read_ep && *usb_write_ep) { - LOG_DEBUG("Claiming interface %d", (int)desc->bInterfaceNumber); - usb_claim_interface(devh, (int)desc->bInterfaceNumber); - return ERROR_OK; - } - } - - return ERROR_FAIL; -} - -int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid) -{ - if (!dev) - return ERROR_FAIL; - - *pid = dev->descriptor.idProduct; - return ERROR_OK; -} diff --git a/src/jtag/drivers/libusb0_common.h b/src/jtag/drivers/libusb0_common.h deleted file mode 100644 index 6f632c462..000000000 --- a/src/jtag/drivers/libusb0_common.h +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * Copyright (C) 2011 by Mauro Gamba * - * * - * 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 * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H -#define OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H - -#include - -#define jtag_libusb_device usb_device -#define jtag_libusb_device_handle usb_dev_handle -#define jtag_libusb_device_descriptor usb_device_descriptor -#define jtag_libusb_interface usb_interface -#define jtag_libusb_interface_descriptor usb_interface_descriptor -#define jtag_libusb_endpoint_descriptor usb_endpoint_descriptor -#define jtag_libusb_config_descriptor usb_config_descriptor - -#define jtag_libusb_reset_device(dev) usb_reset(dev) -#define jtag_libusb_get_device(devh) usb_device(devh) - -/* make some defines compatible to libusb1 */ -#define LIBUSB_REQUEST_TYPE_VENDOR USB_TYPE_VENDOR -#define LIBUSB_RECIPIENT_DEVICE USB_RECIP_DEVICE -#define LIBUSB_ENDPOINT_OUT USB_ENDPOINT_OUT -#define LIBUSB_ENDPOINT_IN USB_ENDPOINT_IN -#define LIBUSB_TRANSFER_TYPE_BULK USB_ENDPOINT_TYPE_BULK - -static inline int jtag_libusb_claim_interface(jtag_libusb_device_handle *devh, - int iface) -{ - return usb_claim_interface(devh, iface); -}; - -static inline int jtag_libusb_release_interface(jtag_libusb_device_handle *devh, - int iface) -{ - return usb_release_interface(devh, iface); -} - -int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, - struct jtag_libusb_device_handle **out); -void jtag_libusb_close(jtag_libusb_device_handle *dev); -int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, - uint8_t requestType, uint8_t request, uint16_t wValue, - uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout); -int jtag_libusb_bulk_write(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout, int *transferred); -int jtag_libusb_bulk_read(struct jtag_libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout, int *transferred); -int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, - int configuration); -int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, - unsigned int *usb_read_ep, - unsigned int *usb_write_ep, - int bclass, int subclass, int protocol, int trans_type); -int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid); - -#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB0_COMMON_H */ diff --git a/src/jtag/drivers/libusb_common.h b/src/jtag/drivers/libusb_common.h index 599a0a9b0..47aca5d91 100644 --- a/src/jtag/drivers/libusb_common.h +++ b/src/jtag/drivers/libusb_common.h @@ -20,8 +20,6 @@ #ifdef HAVE_LIBUSB1 #include "libusb1_common.h" -#else -#include "libusb0_common.h" #endif #endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H */ From 8ce51b6a207e8cefdf5b6cb06d3c57d1cbef5a99 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 7 Jan 2020 22:53:28 +0100 Subject: [PATCH 163/354] tcl/target: Drop old Renesas Gen2 SoC configs Drop old Renesas Gen2 SoC configurations, as they were superseded by the new unified config. Change-Id: I7c2ccbdc13b01a552ce9cafdc1538f226beaa9f2 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5399 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/target/renesas_r8a7790.cfg | 36 ---------------------------------- tcl/target/renesas_r8a7791.cfg | 27 ------------------------- tcl/target/renesas_r8a7794.cfg | 27 ------------------------- 3 files changed, 90 deletions(-) delete mode 100644 tcl/target/renesas_r8a7790.cfg delete mode 100644 tcl/target/renesas_r8a7791.cfg delete mode 100644 tcl/target/renesas_r8a7794.cfg diff --git a/tcl/target/renesas_r8a7790.cfg b/tcl/target/renesas_r8a7790.cfg deleted file mode 100644 index a662b6b37..000000000 --- a/tcl/target/renesas_r8a7790.cfg +++ /dev/null @@ -1,36 +0,0 @@ -# Renesas R-Car H2 -# https://www.renesas.com/en-us/solutions/automotive/products/rcar-h2.html - -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x4ba00477 -} - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME r8a7790 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID - -# Configuring only one core using DAP. -# Base addresses of Cortex A15 cores: -# core 0 - 0x800B0000 -# core 1 - 0x800B2000 -# core 2 - 0x800B4000 -# core 3 - 0x800B6000 -# Base addresses of Cortex A7 cores (not supported yet): -# core 0 - 0x800F0000 -# core 1 - 0x800F2000 -# core 2 - 0x800F4000 -# core 3 - 0x800F6000 -set _TARGETNAME $_CHIPNAME.ca15. -dap create ${_CHIPNAME}.dap -chain-position $_CHIPNAME.cpu -target create ${_TARGETNAME}0 cortex_a -dap ${_CHIPNAME}.dap -coreid 0 -dbgbase 0x800B0000 -target create ${_TARGETNAME}1 cortex_a -dap ${_CHIPNAME}.dap -coreid 1 -dbgbase 0x800B2000 -defer-examine -target create ${_TARGETNAME}2 cortex_a -dap ${_CHIPNAME}.dap -coreid 2 -dbgbase 0x800B4000 -defer-examine -target create ${_TARGETNAME}3 cortex_a -dap ${_CHIPNAME}.dap -coreid 3 -dbgbase 0x800B6000 -defer-examine - -targets ${_TARGETNAME}0 diff --git a/tcl/target/renesas_r8a7791.cfg b/tcl/target/renesas_r8a7791.cfg deleted file mode 100644 index f93cbb8f1..000000000 --- a/tcl/target/renesas_r8a7791.cfg +++ /dev/null @@ -1,27 +0,0 @@ -# Renesas R-Car M2 -# https://www.renesas.com/en-us/solutions/automotive/products/rcar-m2.html - -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x4ba00477 -} - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME r8a7791 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID - -# Configuring only one core using DAP. -# Base addresses of cores: -# core 0 - 0x800B0000 -# core 1 - 0x800B2000 -set _TARGETNAME $_CHIPNAME.ca15. -dap create ${_CHIPNAME}.dap -chain-position $_CHIPNAME.cpu -target create ${_TARGETNAME}0 cortex_a -dap ${_CHIPNAME}.dap -coreid 0 -dbgbase 0x800B0000 -target create ${_TARGETNAME}1 cortex_a -dap ${_CHIPNAME}.dap -coreid 1 -dbgbase 0x800B2000 -defer-examine - -targets ${_TARGETNAME}0 diff --git a/tcl/target/renesas_r8a7794.cfg b/tcl/target/renesas_r8a7794.cfg deleted file mode 100644 index e3e27246c..000000000 --- a/tcl/target/renesas_r8a7794.cfg +++ /dev/null @@ -1,27 +0,0 @@ -# Renesas R-Car E2 -# https://www.renesas.com/en-us/solutions/automotive/products/rcar-e2.html - -if { [info exists DAP_TAPID] } { - set _DAP_TAPID $DAP_TAPID -} else { - set _DAP_TAPID 0x4ba00477 -} - -if { [info exists CHIPNAME] } { - set _CHIPNAME $CHIPNAME -} else { - set _CHIPNAME r8a7794 -} - -jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID - -# Configuring only one core using DAP. -# Base addresses of cores: -# core 0 - 0x800F0000 -# core 1 - 0x800F2000 -set _TARGETNAME $_CHIPNAME.ca7. -dap create ${_CHIPNAME}.dap -chain-position $_CHIPNAME.cpu -target create ${_TARGETNAME}0 cortex_a -dap ${_CHIPNAME}.dap -coreid 0 -dbgbase 0x800F0000 -target create ${_TARGETNAME}1 cortex_a -dap ${_CHIPNAME}.dap -coreid 1 -dbgbase 0x800F2000 -defer-examine - -targets ${_TARGETNAME}0 From 93c6bf2cce5f23e37d4a1dd5136a40e74c69285c Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Wed, 5 Feb 2020 15:50:31 +0100 Subject: [PATCH 164/354] drivers: libusb1_common code cleanup Remove unncessary wrapper functions and 'jtag_' prefixes. Change-Id: I0fd866ff1e1cf7386c4d58a808dfda2c1c0a1518 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5433 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/jtag/aice/aice_usb.c | 18 ++++----- src/jtag/aice/aice_usb.h | 2 +- src/jtag/drivers/ft232r.c | 6 +-- src/jtag/drivers/kitprog.c | 4 +- src/jtag/drivers/libusb1_common.c | 22 +++++------ src/jtag/drivers/libusb1_common.h | 39 ++++--------------- src/jtag/drivers/opendous.c | 6 +-- src/jtag/drivers/openjtag.c | 2 +- src/jtag/drivers/osbdm.c | 4 +- src/jtag/drivers/stlink_usb.c | 12 +++--- .../usb_blaster/ublast2_access_libusb.c | 6 +-- src/jtag/drivers/usb_blaster/ublast_access.h | 2 +- 12 files changed, 50 insertions(+), 73 deletions(-) diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index 9e4741342..8c3a629a0 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -349,8 +349,8 @@ static void aice_unpack_dthmb(uint8_t *cmd_ack_code, uint8_t *target_id, /* calls the given usb_bulk_* function, allowing for the data to * trickle in with some timeouts */ static int usb_bulk_with_retries( - int (*f)(jtag_libusb_device_handle *, int, char *, int, int, int *), - jtag_libusb_device_handle *dev, int ep, + int (*f)(libusb_device_handle *, int, char *, int, int, int *), + libusb_device_handle *dev, int ep, char *bytes, int size, int timeout, int *transferred) { int tries = 3, count = 0; @@ -369,7 +369,7 @@ static int usb_bulk_with_retries( return ERROR_OK; } -static int wrap_usb_bulk_write(jtag_libusb_device_handle *dev, int ep, +static int wrap_usb_bulk_write(libusb_device_handle *dev, int ep, char *buff, int size, int timeout, int *transferred) { @@ -379,7 +379,7 @@ static int wrap_usb_bulk_write(jtag_libusb_device_handle *dev, int ep, return 0; } -static inline int usb_bulk_write_ex(jtag_libusb_device_handle *dev, int ep, +static inline int usb_bulk_write_ex(libusb_device_handle *dev, int ep, char *bytes, int size, int timeout) { int tr = 0; @@ -389,7 +389,7 @@ static inline int usb_bulk_write_ex(jtag_libusb_device_handle *dev, int ep, return tr; } -static inline int usb_bulk_read_ex(jtag_libusb_device_handle *dev, int ep, +static inline int usb_bulk_read_ex(struct libusb_device_handle *dev, int ep, char *bytes, int size, int timeout) { int tr = 0; @@ -2107,7 +2107,7 @@ static int aice_usb_open(struct aice_port_param_s *param) { const uint16_t vids[] = { param->vid, 0 }; const uint16_t pids[] = { param->pid, 0 }; - struct jtag_libusb_device_handle *devh; + struct libusb_device_handle *devh; if (jtag_libusb_open(vids, pids, NULL, &devh) != ERROR_OK) return ERROR_FAIL; @@ -2125,7 +2125,7 @@ static int aice_usb_open(struct aice_port_param_s *param) #if IS_WIN32 == 0 - jtag_libusb_reset_device(devh); + libusb_reset_device(devh); #if IS_DARWIN == 0 @@ -2146,8 +2146,8 @@ static int aice_usb_open(struct aice_port_param_s *param) #endif /* usb_set_configuration required under win32 */ - jtag_libusb_set_configuration(devh, 0); - jtag_libusb_claim_interface(devh, 0); + libusb_set_configuration(devh, 0); + libusb_claim_interface(devh, 0); unsigned int aice_read_ep; unsigned int aice_write_ep; diff --git a/src/jtag/aice/aice_usb.h b/src/jtag/aice/aice_usb.h index 15cc1f60d..04021de3b 100644 --- a/src/jtag/aice/aice_usb.h +++ b/src/jtag/aice/aice_usb.h @@ -93,7 +93,7 @@ struct aice_usb_handler_s { unsigned int usb_read_ep; unsigned int usb_write_ep; - struct jtag_libusb_device_handle *usb_handle; + struct libusb_device_handle *usb_handle; }; struct cache_info { diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index c20367fc0..8fe63bb35 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -71,7 +71,7 @@ static char *ft232r_serial_desc; static uint16_t ft232r_vid = 0x0403; /* FTDI */ static uint16_t ft232r_pid = 0x6001; /* FT232R */ -static jtag_libusb_device_handle *adapter; +static struct libusb_device_handle *adapter; static uint8_t *ft232r_output; static size_t ft232r_output_len; @@ -268,7 +268,7 @@ static int ft232r_init(void) else /* serial port will be restored after jtag: */ libusb_set_auto_detach_kernel_driver(adapter, 1); /* 1: DONT_DETACH_SIO_MODULE */ - if (jtag_libusb_claim_interface(adapter, 0)) { + if (libusb_claim_interface(adapter, 0)) { LOG_ERROR("unable to claim interface"); return ERROR_JTAG_INIT_FAILED; } @@ -330,7 +330,7 @@ static int ft232r_quit(void) } } - if (jtag_libusb_release_interface(adapter, 0) != 0) + if (libusb_release_interface(adapter, 0) != 0) LOG_ERROR("usb release interface failed"); jtag_libusb_close(adapter); diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index 7b339aa0b..e26f5aa92 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -95,7 +95,7 @@ struct kitprog { hid_device *hid_handle; - struct jtag_libusb_device_handle *usb_handle; + struct libusb_device_handle *usb_handle; uint16_t packet_size; uint16_t packet_index; uint8_t *packet_buffer; @@ -311,7 +311,7 @@ static int kitprog_usb_open(void) } /* Claim the KitProg Programmer (bulk transfer) interface */ - if (jtag_libusb_claim_interface(kitprog_handle->usb_handle, 1) != ERROR_OK) { + if (libusb_claim_interface(kitprog_handle->usb_handle, 1) != ERROR_OK) { LOG_ERROR("Failed to claim KitProg Programmer (bulk transfer) interface"); return ERROR_FAIL; } diff --git a/src/jtag/drivers/libusb1_common.c b/src/jtag/drivers/libusb1_common.c index 0d4bcbab6..607b6d4aa 100644 --- a/src/jtag/drivers/libusb1_common.c +++ b/src/jtag/drivers/libusb1_common.c @@ -125,12 +125,12 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *serial, - struct jtag_libusb_device_handle **out) + struct libusb_device_handle **out) { int cnt, idx, errCode; int retval = ERROR_FAIL; bool serial_mismatch = false; - struct jtag_libusb_device_handle *libusb_handle = NULL; + struct libusb_device_handle *libusb_handle = NULL; if (libusb_init(&jtag_libusb_context) < 0) return ERROR_FAIL; @@ -180,7 +180,7 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], return retval; } -void jtag_libusb_close(jtag_libusb_device_handle *dev) +void jtag_libusb_close(struct libusb_device_handle *dev) { /* Close device */ libusb_close(dev); @@ -188,7 +188,7 @@ void jtag_libusb_close(jtag_libusb_device_handle *dev) libusb_exit(jtag_libusb_context); } -int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t requestType, +int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t requestType, uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout) { @@ -203,7 +203,7 @@ int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t request return transferred; } -int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes, +int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, char *bytes, int size, int timeout, int *transferred) { int ret; @@ -220,7 +220,7 @@ int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes, return ERROR_OK; } -int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes, +int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, char *bytes, int size, int timeout, int *transferred) { int ret; @@ -237,10 +237,10 @@ int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes, return ERROR_OK; } -int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, +int jtag_libusb_set_configuration(struct libusb_device_handle *devh, int configuration) { - struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); + struct libusb_device *udev = libusb_get_device(devh); int retCode = -99; struct libusb_config_descriptor *config = NULL; @@ -265,12 +265,12 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, return retCode; } -int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, +int jtag_libusb_choose_interface(struct libusb_device_handle *devh, unsigned int *usb_read_ep, unsigned int *usb_write_ep, int bclass, int subclass, int protocol, int trans_type) { - struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); + struct libusb_device *udev = libusb_get_device(devh); const struct libusb_interface *inter; const struct libusb_interface_descriptor *interdesc; const struct libusb_endpoint_descriptor *epdesc; @@ -317,7 +317,7 @@ int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, return ERROR_FAIL; } -int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid) +int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid) { struct libusb_device_descriptor dev_desc; diff --git a/src/jtag/drivers/libusb1_common.h b/src/jtag/drivers/libusb1_common.h index 34be691f5..b132e26ae 100644 --- a/src/jtag/drivers/libusb1_common.h +++ b/src/jtag/drivers/libusb1_common.h @@ -22,41 +22,18 @@ #include -#define jtag_libusb_device libusb_device -#define jtag_libusb_device_handle libusb_device_handle -#define jtag_libusb_device_descriptor libusb_device_descriptor -#define jtag_libusb_interface libusb_interface -#define jtag_libusb_interface_descriptor libusb_interface_descriptor -#define jtag_libusb_endpoint_descriptor libusb_endpoint_descriptor -#define jtag_libusb_config_descriptor libusb_config_descriptor - -#define jtag_libusb_reset_device(dev) libusb_reset_device(dev) -#define jtag_libusb_get_device(devh) libusb_get_device(devh) - -static inline int jtag_libusb_claim_interface(jtag_libusb_device_handle *devh, - int iface) -{ - return libusb_claim_interface(devh, iface); -}; - -static inline int jtag_libusb_release_interface(jtag_libusb_device_handle *devh, - int iface) -{ - return libusb_release_interface(devh, iface); -} - int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *serial, - struct jtag_libusb_device_handle **out); -void jtag_libusb_close(jtag_libusb_device_handle *dev); -int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, + struct libusb_device_handle **out); +void jtag_libusb_close(struct libusb_device_handle *dev); +int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t requestType, uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout); -int jtag_libusb_bulk_write(struct jtag_libusb_device_handle *dev, int ep, +int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, char *bytes, int size, int timeout, int *transferred); -int jtag_libusb_bulk_read(struct jtag_libusb_device_handle *dev, int ep, +int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, char *bytes, int size, int timeout, int *transferred); -int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, +int jtag_libusb_set_configuration(struct libusb_device_handle *devh, int configuration); /** * Find the first interface optionally matching class, subclass and @@ -72,10 +49,10 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, * @param trans_type `bmAttributes Bits 0..1 Transfer type` to match, or -1 to ignore this field. * @returns Returns ERROR_OK on success, ERROR_FAIL otherwise. */ -int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, +int jtag_libusb_choose_interface(struct libusb_device_handle *devh, unsigned int *usb_read_ep, unsigned int *usb_write_ep, int bclass, int subclass, int protocol, int trans_type); -int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid); +int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid); #endif /* OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H */ diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index d5c279b08..18d954308 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -134,7 +134,7 @@ static void opendous_tap_append_scan(int length, uint8_t *buffer, struct scan_co /* opendous lowlevel functions */ struct opendous_jtag { - struct jtag_libusb_device_handle *usb_handle; + struct libusb_device_handle *usb_handle; }; static struct opendous_jtag *opendous_usb_open(void); @@ -714,12 +714,12 @@ struct opendous_jtag *opendous_usb_open(void) { struct opendous_jtag *result; - struct jtag_libusb_device_handle *devh; + struct libusb_device_handle *devh; if (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, NULL, &devh) != ERROR_OK) return NULL; jtag_libusb_set_configuration(devh, 0); - jtag_libusb_claim_interface(devh, 0); + libusb_claim_interface(devh, 0); result = malloc(sizeof(*result)); result->usb_handle = devh; diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index c42b620bb..3bfcccf6e 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -111,7 +111,7 @@ static uint8_t usb_rx_buf[OPENJTAG_BUFFER_SIZE]; static struct openjtag_scan_result openjtag_scan_result_buffer[OPENJTAG_MAX_PENDING_RESULTS]; static int openjtag_scan_result_count; -static jtag_libusb_device_handle *usbh; +static struct libusb_device_handle *usbh; /* CY7C65215 model only */ #define CY7C65215_JTAG_REQUEST 0x40 /* bmRequestType: vendor host-to-device */ diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index 3323557b7..30c46234e 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -132,7 +132,7 @@ static const uint16_t osbdm_vid[] = { 0x15a2, 0x15a2, 0x15a2, 0 }; static const uint16_t osbdm_pid[] = { 0x0042, 0x0058, 0x005e, 0 }; struct osbdm { - struct jtag_libusb_device_handle *devh; /* USB handle */ + struct libusb_device_handle *devh; /* USB handle */ uint8_t buffer[OSBDM_USB_BUFSIZE]; /* Data to send and receive */ int count; /* Count data to send and to read */ }; @@ -377,7 +377,7 @@ static int osbdm_open(struct osbdm *osbdm) if (jtag_libusb_open(osbdm_vid, osbdm_pid, NULL, &osbdm->devh) != ERROR_OK) return ERROR_FAIL; - if (jtag_libusb_claim_interface(osbdm->devh, 0) != ERROR_OK) + if (libusb_claim_interface(osbdm->devh, 0) != ERROR_OK) return ERROR_FAIL; return ERROR_OK; diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index da1d1b564..a186dfdef 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -111,7 +111,7 @@ struct stlink_usb_version { /** */ struct stlink_usb_handle_s { /** */ - struct jtag_libusb_device_handle *fd; + struct libusb_device_handle *fd; /** */ struct libusb_transfer *trans; /** */ @@ -451,7 +451,7 @@ struct jtag_xfer { }; static int jtag_libusb_bulk_transfer_n( - jtag_libusb_device_handle * dev_handle, + struct libusb_device_handle *dev_handle, struct jtag_xfer *transfers, size_t n_transfers, int timeout) @@ -2785,7 +2785,7 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) jtag_libusb_set_configuration(h->fd, 0); - if (jtag_libusb_claim_interface(h->fd, 0) != ERROR_OK) { + if (libusb_claim_interface(h->fd, 0) != ERROR_OK) { LOG_DEBUG("claim interface failed"); goto error_open; } @@ -2794,7 +2794,7 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) h->rx_ep = STLINK_RX_EP; uint16_t pid; - if (jtag_libusb_get_pid(jtag_libusb_get_device(h->fd), &pid) != ERROR_OK) { + if (jtag_libusb_get_pid(libusb_get_device(h->fd), &pid) != ERROR_OK) { LOG_DEBUG("libusb_get_pid failed"); goto error_open; } @@ -2838,13 +2838,13 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) LOG_ERROR("read version failed"); goto error_open; } else { - err = jtag_libusb_release_interface(h->fd, 0); + err = libusb_release_interface(h->fd, 0); if (err != ERROR_OK) { LOG_ERROR("release interface failed"); goto error_open; } - err = jtag_libusb_reset_device(h->fd); + err = libusb_reset_device(h->fd); if (err != ERROR_OK) { LOG_ERROR("reset device failed"); goto error_open; diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c index fb1e4440a..34fbb8952 100644 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c @@ -72,7 +72,7 @@ static int ublast2_libusb_write(struct ublast_lowlevel *low, uint8_t *buf, } -static int ublast2_write_firmware_section(struct jtag_libusb_device_handle *libusb_dev, +static int ublast2_write_firmware_section(struct libusb_device_handle *libusb_dev, struct image *firmware_image, int section_index) { uint16_t chunk_size; @@ -123,7 +123,7 @@ static int ublast2_write_firmware_section(struct jtag_libusb_device_handle *libu return ERROR_OK; } -static int load_usb_blaster_firmware(struct jtag_libusb_device_handle *libusb_dev, +static int load_usb_blaster_firmware(struct libusb_device_handle *libusb_dev, struct ublast_lowlevel *low) { struct image ublast2_firmware_image; @@ -191,7 +191,7 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low) { const uint16_t vids[] = { low->ublast_vid_uninit, 0 }; const uint16_t pids[] = { low->ublast_pid_uninit, 0 }; - struct jtag_libusb_device_handle *temp; + struct libusb_device_handle *temp; bool renumeration = false; int ret; diff --git a/src/jtag/drivers/usb_blaster/ublast_access.h b/src/jtag/drivers/usb_blaster/ublast_access.h index 252f003a9..5178ae10b 100644 --- a/src/jtag/drivers/usb_blaster/ublast_access.h +++ b/src/jtag/drivers/usb_blaster/ublast_access.h @@ -39,7 +39,7 @@ struct ublast_lowlevel { uint16_t ublast_vid_uninit; uint16_t ublast_pid_uninit; char *ublast_device_desc; - struct jtag_libusb_device_handle *libusb_dev; + struct libusb_device_handle *libusb_dev; char *firmware_path; int (*write)(struct ublast_lowlevel *low, uint8_t *buf, int size, From 51dd4ce6bbc3c6f200001640f2cb1638b5185cb7 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Wed, 5 Feb 2020 16:07:48 +0100 Subject: [PATCH 165/354] drivers: Rename 'libusb1_common' to 'libusb_helper' The name 'common' does not make sense anymore. While at it, remove some unnecessary #includes. Change-Id: If9798a5cce179438d89428a598d8ca05c8e5f20c Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5434 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/jtag/aice/aice_interface.c | 1 - src/jtag/aice/aice_usb.c | 2 +- src/jtag/drivers/Makefile.am | 5 ++-- src/jtag/drivers/ft232r.c | 2 +- src/jtag/drivers/kitprog.c | 2 +- src/jtag/drivers/libusb_common.h | 25 ------------------- .../{libusb1_common.c => libusb_helper.c} | 2 +- .../{libusb1_common.h => libusb_helper.h} | 6 ++--- src/jtag/drivers/opendous.c | 2 +- src/jtag/drivers/openjtag.c | 2 +- src/jtag/drivers/osbdm.c | 2 +- src/jtag/drivers/stlink_usb.c | 2 +- .../usb_blaster/ublast2_access_libusb.c | 2 +- src/jtag/drivers/usb_blaster/ublast_access.h | 2 -- 14 files changed, 14 insertions(+), 43 deletions(-) delete mode 100644 src/jtag/drivers/libusb_common.h rename src/jtag/drivers/{libusb1_common.c => libusb_helper.c} (99%) rename src/jtag/drivers/{libusb1_common.h => libusb_helper.h} (95%) diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c index f9bd87eeb..90871a138 100644 --- a/src/jtag/aice/aice_interface.c +++ b/src/jtag/aice/aice_interface.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "aice_usb.h" #define AICE_KHZ_TO_SPEED_MAP_SIZE 16 diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index 8c3a629a0..5fefdd0b4 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -19,7 +19,7 @@ #include "config.h" #endif -#include +#include #include #include #include diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index 47b19470e..aea09b38c 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -22,7 +22,7 @@ DRIVERFILES += %D%/driver.c DRIVERFILES += %D%/jtag_usb_common.c if USE_LIBUSB1 -DRIVERFILES += %D%/libusb1_common.c +DRIVERFILES += %D%/libusb_helper.c %C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBUSB1_CFLAGS) %C%_libocdjtagdrivers_la_LIBADD += $(LIBUSB1_LIBS) endif @@ -168,8 +168,7 @@ DRIVERHEADERS = \ %D%/bitbang.h \ %D%/bitq.h \ %D%/jtag_usb_common.h \ - %D%/libusb1_common.h \ - %D%/libusb_common.h \ + %D%/libusb_helper.h \ %D%/minidriver_imp.h \ %D%/mpsse.h \ %D%/rlink.h \ diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index 8fe63bb35..4812362a3 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -29,7 +29,7 @@ #include #include #include -#include "libusb1_common.h" +#include "libusb_helper.h" /* system includes */ #include diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index e26f5aa92..0c1e74c42 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -43,7 +43,7 @@ #include #include -#include "libusb_common.h" +#include "libusb_helper.h" #define VID 0x04b4 #define PID 0xf139 diff --git a/src/jtag/drivers/libusb_common.h b/src/jtag/drivers/libusb_common.h deleted file mode 100644 index 47aca5d91..000000000 --- a/src/jtag/drivers/libusb_common.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mauro Gamba * - * * - * 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 * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H -#define OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H - -#ifdef HAVE_LIBUSB1 -#include "libusb1_common.h" -#endif - -#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H */ diff --git a/src/jtag/drivers/libusb1_common.c b/src/jtag/drivers/libusb_helper.c similarity index 99% rename from src/jtag/drivers/libusb1_common.c rename to src/jtag/drivers/libusb_helper.c index 607b6d4aa..5a8129cb9 100644 --- a/src/jtag/drivers/libusb1_common.c +++ b/src/jtag/drivers/libusb_helper.c @@ -21,7 +21,7 @@ #include "config.h" #endif #include -#include "libusb1_common.h" +#include "libusb_helper.h" #include "log.h" /* diff --git a/src/jtag/drivers/libusb1_common.h b/src/jtag/drivers/libusb_helper.h similarity index 95% rename from src/jtag/drivers/libusb1_common.h rename to src/jtag/drivers/libusb_helper.h index b132e26ae..46e4954e7 100644 --- a/src/jtag/drivers/libusb1_common.h +++ b/src/jtag/drivers/libusb_helper.h @@ -17,8 +17,8 @@ * along with this program. If not, see . * ***************************************************************************/ -#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H -#define OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H +#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H +#define OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H #include @@ -55,4 +55,4 @@ int jtag_libusb_choose_interface(struct libusb_device_handle *devh, int bclass, int subclass, int protocol, int trans_type); int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid); -#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H */ +#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H */ diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index 18d954308..7298a2a10 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -32,7 +32,7 @@ #include #include -#include "libusb_common.h" +#include "libusb_helper.h" #include #include diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 3bfcccf6e..7b07813d8 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -45,7 +45,7 @@ #include #include -#include "libusb_common.h" +#include "libusb_helper.h" static enum { OPENJTAG_VARIANT_STANDARD, diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index 30c46234e..aea126d0d 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -23,7 +23,7 @@ #include #include #include -#include "libusb_common.h" +#include "libusb_helper.h" struct sequence { int len; diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index a186dfdef..ca7a4df4e 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -41,7 +41,7 @@ #include -#include "libusb_common.h" +#include "libusb_helper.h" #ifdef HAVE_LIBUSB1 #define USE_LIBUSB_ASYNCIO diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c index 34fbb8952..4f7ee6300 100644 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c @@ -23,7 +23,7 @@ #endif #include #include -#include +#include #include #include "ublast_access.h" diff --git a/src/jtag/drivers/usb_blaster/ublast_access.h b/src/jtag/drivers/usb_blaster/ublast_access.h index 5178ae10b..ad20d65d4 100644 --- a/src/jtag/drivers/usb_blaster/ublast_access.h +++ b/src/jtag/drivers/usb_blaster/ublast_access.h @@ -28,8 +28,6 @@ #ifndef OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H #define OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H -#include - /* Low level flags */ #define COPY_TDO_BUFFER (1 << 0) From 122c80087c3e66ecf5122d99081bcd83ab08fddc Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Tue, 28 Jan 2020 10:53:35 +0100 Subject: [PATCH 166/354] flash/nor/stm32f1x: Group and cleanup device list Group device list based on the device family and add clear device family names. Change-Id: I7a2dab1d1c0c8d141df02656c1964cb2c3fcbcd1 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5423 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Tomas Vanek Reviewed-by: Oleksij Rempel --- src/flash/nor/stm32f1x.c | 74 ++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index ba0d54e79..7d5a8f0a2 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -713,31 +713,63 @@ static int stm32x_probe(struct flash_bank *bank) /* set page size, protection granularity and max flash size depending on family */ switch (device_id & 0xfff) { - case 0x410: /* medium density */ + case 0x440: /* stm32f05x */ + case 0x444: /* stm32f03x */ + case 0x445: /* stm32f04x */ + page_size = 1024; + stm32x_info->ppage_size = 4; + max_flash_size_in_kb = 64; + stm32x_info->user_data_offset = 16; + stm32x_info->option_offset = 6; + stm32x_info->default_rdp = 0xAA; + stm32x_info->can_load_options = true; + break; + case 0x448: /* stm32f07x */ + case 0x442: /* stm32f09x */ + page_size = 2048; + stm32x_info->ppage_size = 4; + max_flash_size_in_kb = 256; + stm32x_info->user_data_offset = 16; + stm32x_info->option_offset = 6; + stm32x_info->default_rdp = 0xAA; + stm32x_info->can_load_options = true; + break; + case 0x410: /* stm32f1x medium-density */ page_size = 1024; stm32x_info->ppage_size = 4; max_flash_size_in_kb = 128; break; - case 0x412: /* low density */ + case 0x412: /* stm32f1x low-density */ page_size = 1024; stm32x_info->ppage_size = 4; max_flash_size_in_kb = 32; break; - case 0x414: /* high density */ + case 0x414: /* stm32f1x high-density */ page_size = 2048; stm32x_info->ppage_size = 2; max_flash_size_in_kb = 512; break; - case 0x418: /* connectivity line density */ + case 0x418: /* stm32f1x connectivity */ page_size = 2048; stm32x_info->ppage_size = 2; max_flash_size_in_kb = 256; break; - case 0x420: /* value line density */ + case 0x430: /* stm32f1 XL-density (dual flash banks) */ + page_size = 2048; + stm32x_info->ppage_size = 2; + max_flash_size_in_kb = 1024; + stm32x_info->has_dual_banks = true; + break; + case 0x420: /* stm32f100xx low- and medium-density value line */ page_size = 1024; stm32x_info->ppage_size = 4; max_flash_size_in_kb = 128; break; + case 0x428: /* stm32f100xx high-density value line */ + page_size = 2048; + stm32x_info->ppage_size = 4; + max_flash_size_in_kb = 128; + break; case 0x422: /* stm32f302/3xb/c */ page_size = 2048; stm32x_info->ppage_size = 2; @@ -756,17 +788,6 @@ static int stm32x_probe(struct flash_bank *bank) stm32x_info->default_rdp = 0xAA; stm32x_info->can_load_options = true; break; - case 0x428: /* value line High density */ - page_size = 2048; - stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 128; - break; - case 0x430: /* xl line density (dual flash banks) */ - page_size = 2048; - stm32x_info->ppage_size = 2; - max_flash_size_in_kb = 1024; - stm32x_info->has_dual_banks = true; - break; case 0x432: /* stm32f37x */ page_size = 2048; stm32x_info->ppage_size = 2; @@ -786,27 +807,6 @@ static int stm32x_probe(struct flash_bank *bank) stm32x_info->default_rdp = 0xAA; stm32x_info->can_load_options = true; break; - case 0x440: /* stm32f05x */ - case 0x444: /* stm32f03x */ - case 0x445: /* stm32f04x */ - page_size = 1024; - stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 64; - stm32x_info->user_data_offset = 16; - stm32x_info->option_offset = 6; - stm32x_info->default_rdp = 0xAA; - stm32x_info->can_load_options = true; - break; - case 0x448: /* stm32f07x */ - case 0x442: /* stm32f09x */ - page_size = 2048; - stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 256; - stm32x_info->user_data_offset = 16; - stm32x_info->option_offset = 6; - stm32x_info->default_rdp = 0xAA; - stm32x_info->can_load_options = true; - break; default: LOG_WARNING("Cannot identify target as a STM32 family."); return ERROR_FAIL; From b8524295002076a3f0e9e2211298a69a6ba9d858 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:18:37 +0100 Subject: [PATCH 167/354] src/flash/nor/at91sam3|4l|7: fix clang static analyzer warnings Change-Id: I5cd2b2ebb2bd1980bdd1632b5c35bda9718a1089 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5365 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/flash/nor/at91sam3.c | 3 ++- src/flash/nor/at91sam4l.c | 1 + src/flash/nor/at91sam7.c | 7 +------ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c index 2457c15f3..af0b50b49 100644 --- a/src/flash/nor/at91sam3.c +++ b/src/flash/nor/at91sam3.c @@ -3653,7 +3653,8 @@ showall: } if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) { r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v); - command_print(CMD, "sam3-gpnvm%u: %u", who, v); + if (r == ERROR_OK) + command_print(CMD, "sam3-gpnvm%u: %u", who, v); return r; } else { command_print(CMD, "sam3-gpnvm invalid GPNVM: %u", who); diff --git a/src/flash/nor/at91sam4l.c b/src/flash/nor/at91sam4l.c index d356398dc..d4bfe5310 100644 --- a/src/flash/nor/at91sam4l.c +++ b/src/flash/nor/at91sam4l.c @@ -601,6 +601,7 @@ static int sam4l_write(struct flash_bank *bank, const uint8_t *buffer, /* There's at least one aligned page to write out. */ if (count >= chip->page_size) { + assert(chip->page_size > 0); int np = count / chip->page_size + ((count % chip->page_size) ? 1 : 0); for (int i = 0; i < np; i++) { diff --git a/src/flash/nor/at91sam7.c b/src/flash/nor/at91sam7.c index 232260b93..039746c16 100644 --- a/src/flash/nor/at91sam7.c +++ b/src/flash/nor/at91sam7.c @@ -711,8 +711,6 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command) uint16_t page_size; uint16_t num_nvmbits; - char *target_name_t; - int bnk, sec; at91sam7_info = malloc(sizeof(struct at91sam7_flash_bank)); @@ -753,9 +751,6 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command) return ERROR_OK; } - target_name_t = calloc(strlen(CMD_ARGV[7]) + 1, sizeof(char)); - strcpy(target_name_t, CMD_ARGV[7]); - /* calculate bank size */ bank_size = num_sectors * pages_per_sector * page_size; @@ -794,7 +789,7 @@ FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command) at91sam7_info = t_bank->driver_priv; - at91sam7_info->target_name = target_name_t; + at91sam7_info->target_name = strdup(CMD_ARGV[7]); at91sam7_info->flashmode = 0; at91sam7_info->ext_freq = ext_freq; at91sam7_info->num_nvmbits = num_nvmbits; From e1051e1090d4dce0e45d428345015af285a21d7e Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:23:26 +0100 Subject: [PATCH 168/354] flash/nor/fm4,tms470: fix clang static analyzer warnings Change-Id: I18c1501918d40453fea6aeeb6f035e46d41fc524 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5366 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/flash/nor/fm4.c | 8 +++++--- src/flash/nor/tms470.c | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/flash/nor/fm4.c b/src/flash/nor/fm4.c index a8877b4fb..7e3a1c51f 100644 --- a/src/flash/nor/fm4.c +++ b/src/flash/nor/fm4.c @@ -207,7 +207,7 @@ static int fm4_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t halfword_count = DIV_ROUND_UP(byte_count, 2); uint32_t result; unsigned i; - int retval; + int retval, retval2 = ERROR_OK; const uint8_t write_block_code[] = { #include "../../../contrib/loaders/flash/fm4/write.inc" }; @@ -327,7 +327,7 @@ static int fm4_flash_write(struct flash_bank *bank, const uint8_t *buffer, err_run_ret: err_run: err_write_data: - retval = fm4_enter_flash_cpu_rom_mode(target); + retval2 = fm4_enter_flash_cpu_rom_mode(target); err_flash_mode: for (i = 0; i < ARRAY_SIZE(reg_params); i++) @@ -338,7 +338,9 @@ err_alloc_data: err_write_code: target_free_working_area(target, code_workarea); - return retval; + if (retval != ERROR_OK) + return retval; + return retval2; } static int mb9bf_probe(struct flash_bank *bank) diff --git a/src/flash/nor/tms470.c b/src/flash/nor/tms470.c index 90557b8f1..bc16acab5 100644 --- a/src/flash/nor/tms470.c +++ b/src/flash/nor/tms470.c @@ -709,6 +709,7 @@ static int tms470_erase_sector(struct flash_bank *bank, int sector) * Select one or more bits in FMBSEA or FMBSEB to disable Level 1 * protection for the particular sector to be erased/written. */ + assert(sector >= 0); if (sector < 16) { target_read_u32(target, 0xFFE88008, &fmbsea); target_write_u32(target, 0xFFE88008, fmbsea | (1 << sector)); From c84f75de81ecd70afad0dd66dedd9daa27421fe0 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:26:51 +0100 Subject: [PATCH 169/354] flash/nor/numicro: use flash infrastructure to align write The aligning code generated a clang static analyzer warning and imposed huge memory leak. This part of code was removed and flash infrastructure to alignment is used instead. Not tested on hw! Change-Id: I7c71da87547e71d595a7e7071ae5adcc1cecc827 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5367 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/flash/nor/numicro.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c index c6dbfb851..a4852829e 100644 --- a/src/flash/nor/numicro.c +++ b/src/flash/nor/numicro.c @@ -1548,7 +1548,6 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer, { struct target *target = bank->target; uint32_t timeout, status; - uint8_t *new_buffer = NULL; int retval = ERROR_OK; if (target->state != TARGET_HALTED) { @@ -1566,20 +1565,8 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer, if (retval != ERROR_OK) return retval; - if (count & 0x3) { - uint32_t old_count = count; - count = (old_count | 3) + 1; - new_buffer = malloc(count); - if (new_buffer == NULL) { - LOG_ERROR("odd number of bytes to write and no memory " - "for padding buffer"); - return ERROR_FAIL; - } - LOG_INFO("odd number of bytes to write (%d), extending to %d " - "and padding with 0xff", old_count, count); - memset(new_buffer, 0xff, count); - buffer = memcpy(new_buffer, buffer, old_count); - } + assert(offset % 4 == 0); + assert(count % 4 == 0); uint32_t words_remaining = count / 4; @@ -1597,13 +1584,10 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer, LOG_DEBUG("write longword @ %08X", offset + i); - uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff}; - memcpy(padding, buffer + i, MIN(4, count-i)); - retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + offset + i); if (retval != ERROR_OK) return retval; - retval = target_write_memory(target, NUMICRO_FLASH_ISPDAT, 4, 1, padding); + retval = target_write_memory(target, NUMICRO_FLASH_ISPDAT, 4, 1, buffer + i); if (retval != ERROR_OK) return retval; retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); @@ -1754,6 +1738,7 @@ FLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command) memset(bank_info, 0, sizeof(struct numicro_flash_bank)); bank->driver_priv = bank_info; + bank->write_start_alignment = bank->write_end_alignment = 4; return ERROR_OK; From 6ff852e415fe4ffaab793e5f4fe6f68e3e7fa452 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:32:37 +0100 Subject: [PATCH 170/354] jtag/aice: fix clang static analyzer warnings Change-Id: I6c801c2406cd117f2bcf930a5b329c441ab5f1ff Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5368 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/jtag/aice/aice_transport.c | 1 + src/jtag/aice/aice_usb.c | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c index 15ebcac97..682c6698a 100644 --- a/src/jtag/aice/aice_transport.c +++ b/src/jtag/aice/aice_transport.c @@ -47,6 +47,7 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi, return JIM_ERR; } + assert(pTap->expected_ids); memcpy(new_expected_ids, pTap->expected_ids, expected_len); new_expected_ids[pTap->expected_ids_cnt] = w; diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index 5fefdd0b4..a5cccfef4 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -484,7 +484,9 @@ static int aice_usb_packet_flush(void) i = 0; while (1) { - aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status); + int retval = aice_read_ctrl(AICE_READ_CTRL_BATCH_STATUS, &batch_status); + if (retval != ERROR_OK) + return retval; if (batch_status & 0x1) return ERROR_OK; @@ -1797,8 +1799,8 @@ static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val); static int check_suppressed_exception(uint32_t coreid, uint32_t dbger_value) { - uint32_t ir4_value; - uint32_t ir6_value; + uint32_t ir4_value = 0; + uint32_t ir6_value = 0; /* the default value of handling_suppressed_exception is false */ static bool handling_suppressed_exception; @@ -1852,7 +1854,7 @@ static int check_privilege(uint32_t coreid, uint32_t dbger_value) static int aice_check_dbger(uint32_t coreid, uint32_t expect_status) { uint32_t i = 0; - uint32_t value_dbger; + uint32_t value_dbger = 0; while (1) { aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &value_dbger); @@ -1973,7 +1975,7 @@ static int aice_read_reg(uint32_t coreid, uint32_t num, uint32_t *val) aice_execute_dim(coreid, instructions, 4); - uint32_t value_edmsw; + uint32_t value_edmsw = 0; aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); if (value_edmsw & NDS_EDMSW_WDV) aice_read_dtr(coreid, val); @@ -2018,7 +2020,7 @@ static int aice_write_reg(uint32_t coreid, uint32_t num, uint32_t val) LOG_DEBUG("aice_write_reg, reg_no: 0x%08" PRIx32 ", value: 0x%08" PRIx32, num, val); uint32_t instructions[4]; /** execute instructions in DIM */ - uint32_t value_edmsw; + uint32_t value_edmsw = 0; aice_write_dtr(coreid, val); aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); @@ -2447,7 +2449,7 @@ static int aice_backup_tmp_registers(uint32_t coreid) LOG_DEBUG("backup_tmp_registers -"); /* backup target DTR first(if the target DTR is valid) */ - uint32_t value_edmsw; + uint32_t value_edmsw = 0; aice_read_edmsr(coreid, NDS_EDM_SR_EDMSW, &value_edmsw); core_info[coreid].edmsw_backup = value_edmsw; if (value_edmsw & 0x1) { /* EDMSW.WDV == 1 */ @@ -2614,13 +2616,13 @@ static int aice_usb_halt(uint32_t coreid) aice_init_edm_registers(coreid, false); /** Clear EDM_CTL.DBGIM & EDM_CTL.DBGACKM */ - uint32_t edm_ctl_value; + uint32_t edm_ctl_value = 0; aice_read_edmsr(coreid, NDS_EDM_SR_EDM_CTL, &edm_ctl_value); if (edm_ctl_value & 0x3) aice_write_edmsr(coreid, NDS_EDM_SR_EDM_CTL, edm_ctl_value & ~(0x3)); - uint32_t dbger; - uint32_t acc_ctl_value; + uint32_t dbger = 0; + uint32_t acc_ctl_value = 0; core_info[coreid].debug_under_dex_on = false; aice_read_misc(coreid, NDS_EDM_MISC_DBGER, &dbger); @@ -2661,7 +2663,7 @@ static int aice_usb_halt(uint32_t coreid) * it is only for debugging 'debug exception handler' purpose. * after openocd detaches from target, target behavior is * undefined. */ - uint32_t ir0_value; + uint32_t ir0_value = 0; uint32_t debug_mode_ir0_value; aice_read_reg(coreid, IR0, &ir0_value); debug_mode_ir0_value = ir0_value | 0x408; /* turn on DEX, set POM = 1 */ @@ -4029,7 +4031,7 @@ static int aice_usb_profiling(uint32_t coreid, uint32_t interval, uint32_t itera /* check status */ uint32_t i; - uint32_t batch_status; + uint32_t batch_status = 0; i = 0; while (1) { From b07604cc6aacc5591afd281e0d65ab27280f19b4 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:33:55 +0100 Subject: [PATCH 171/354] jtag/drivers/openjtag: fix clang static analyzer warnings Change-Id: I900ce8157b3e220a4647871080bb9abc772446d1 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5369 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/jtag/drivers/openjtag.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 7b07813d8..6131df914 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -229,7 +229,7 @@ static int openjtag_buf_write_standard( return ERROR_JTAG_DEVICE_ERROR; } - *bytes_written += retval; + *bytes_written = retval; return ERROR_OK; } @@ -652,7 +652,6 @@ static void openjtag_add_scan(uint8_t *buffer, int length, struct scan_command * /* whole byte */ /* bits to transfer */ - bits = 7; command |= (7 << 5); length -= 8; } @@ -690,7 +689,7 @@ static void openjtag_execute_sleep(struct jtag_command *cmd) static void openjtag_set_state(uint8_t openocd_state) { - int8_t state = openjtag_get_tap_state(openocd_state); + uint8_t state = openjtag_get_tap_state(openocd_state); uint8_t buf = 0; buf = 0x01; From 2ebedbdf383601104ed441dda19e107a76cdf248 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:35:12 +0100 Subject: [PATCH 172/354] rtos/linux: fix use of memory after it is freed Discovered by clang static analyzer Change-Id: I9f64a67f281b95562d8fd6e2ebb0ae3f79ae8039 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5371 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/rtos/linux.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/rtos/linux.c b/src/rtos/linux.c index 74172b70a..9e59c41a5 100644 --- a/src/rtos/linux.c +++ b/src/rtos/linux.c @@ -621,17 +621,17 @@ struct threads *liste_del_task(struct threads *task_list, struct threads **t, struct threads *prev) { LOG_INFO("del task %" PRId64, (*t)->threadid); - prev->next = (*t)->next; - - if (prev == task_list) - task_list = prev; + if (prev) + prev->next = (*t)->next; + else + task_list = (*t)->next; /* free content of threads */ if ((*t)->context) free((*t)->context); free(*t); - *t = prev; + *t = prev ? prev : task_list; return task_list; } @@ -725,6 +725,7 @@ int linux_get_tasks(struct target *target, int context) /* check that this thread is not one the current threads already * created */ + uint32_t base_addr; #ifdef PID_CHECK if (!current_pid(linux_os, t->pid)) { @@ -745,12 +746,13 @@ int linux_get_tasks(struct target *target, int context) t->context = cpu_context_read(target, t->base_addr, &t->thread_info_addr); + base_addr = next_task(target, t); } else { /*LOG_INFO("thread %s is a current thread already created",t->name); */ + base_addr = next_task(target, t); free(t); } - uint32_t base_addr = next_task(target, t); t = calloc(1, sizeof(struct threads)); t->base_addr = base_addr; } @@ -1178,7 +1180,7 @@ int linux_gdb_T_packet(struct connection *connection, if (linux_os->threads_needs_update == 0) { struct threads *temp = linux_os->thread_list; - struct threads *prev = linux_os->thread_list; + struct threads *prev = NULL; while (temp != NULL) { if (temp->threadid == threadid) { From 4e981bc27c36e696dc8ace3ab4bab534564770c1 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:43:13 +0100 Subject: [PATCH 173/354] target/arm920t: fix clang static analyzer warning Change-Id: I570dfb8b20a3f187f1fe660343cf0b75691e2c30 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5375 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/arm920t.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/arm920t.c b/src/target/arm920t.c index 2ecf218fd..3ddd19888 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -484,7 +484,7 @@ int arm920t_post_debug_entry(struct target *target) /* EXPORTED to FA256 */ void arm920t_pre_restore_context(struct target *target) { - uint32_t cp15c15; + uint32_t cp15c15 = 0; struct arm920t_common *arm920t = target_to_arm920(target); /* restore i/d fault status and address register */ From a2e822834df52efef5e1bbcb91a6eb1afbf102db Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:56:08 +0100 Subject: [PATCH 174/354] helper/binarybuffer: fix clang static analyzer warnings Writing bits to an uninitialized buffer generated false warnings. Zero buffers before setting them by buf_set_u32|64() (do it only if bit-by-bit copy loop is used, zeroed buffer is not necessary if a fast path write is used) Change-Id: I2f7f8ddb45b0cbd08d3e249534fc51f4b5cc6694 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5383 Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- src/flash/nor/jtagspi.c | 2 +- src/helper/binarybuffer.h | 2 ++ src/jtag/core.c | 2 +- src/jtag/tcl.c | 2 +- src/target/arm_jtag.c | 4 ++-- src/target/avr32_jtag.c | 2 +- src/target/esirisc_jtag.c | 2 +- src/target/etb.c | 12 ++++++------ src/target/etm.c | 8 ++++---- src/target/ls1_sap.c | 4 ++-- src/target/mips_ejtag.c | 6 +++--- src/target/openrisc/or1k_tap_vjtag.c | 2 +- src/target/riscv/riscv-011.c | 4 ++-- src/target/riscv/riscv-013.c | 3 ++- src/target/riscv/riscv.c | 8 ++++---- src/target/xscale.c | 14 +++++++------- 16 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c index a9f2dd4a4..f6e311ab8 100644 --- a/src/flash/nor/jtagspi.c +++ b/src/flash/nor/jtagspi.c @@ -59,7 +59,7 @@ static void jtagspi_set_ir(struct flash_bank *bank) { struct jtagspi_flash_bank *info = bank->driver_priv; struct scan_field field; - uint8_t buf[4]; + uint8_t buf[4] = { 0 }; LOG_DEBUG("loading jtagspi ir"); buf_set_u32(buf, 0, info->tap->ir_length, info->ir); diff --git a/src/helper/binarybuffer.h b/src/helper/binarybuffer.h index 7ac221e47..3f2481d9a 100644 --- a/src/helper/binarybuffer.h +++ b/src/helper/binarybuffer.h @@ -33,6 +33,7 @@ * using the bits in @c value. This routine fast-paths writes * of little-endian, byte-aligned, 32-bit words. * @param _buffer The buffer whose bits will be set. + * Do not use uninitialized buffer or clang static analyzer emits a warning. * @param first The bit offset in @c _buffer to start writing (0-31). * @param num The number of bits from @c value to copy (1-32). * @param value Up to 32 bits that will be copied to _buffer. @@ -62,6 +63,7 @@ static inline void buf_set_u32(uint8_t *_buffer, * using the bits in @c value. This routine fast-paths writes * of little-endian, byte-aligned, 64-bit words. * @param _buffer The buffer whose bits will be set. + * Do not use uninitialized buffer or clang static analyzer emits a warning. * @param first The bit offset in @c _buffer to start writing (0-63). * @param num The number of bits from @c value to copy (1-64). * @param value Up to 64 bits that will be copied to _buffer. diff --git a/src/jtag/core.c b/src/jtag/core.c index 1d59712d1..c5011e522 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1233,7 +1233,7 @@ static int jtag_examine_chain(void) /* Add room for end-of-chain marker. */ max_taps++; - uint8_t *idcode_buffer = malloc(max_taps * 4); + uint8_t *idcode_buffer = calloc(4, max_taps); if (idcode_buffer == NULL) return ERROR_JTAG_INIT_FAILED; diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index ba0cb1d1e..734b9c1cb 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -1131,7 +1131,7 @@ COMMAND_HANDLER(handle_irscan_command) } int field_size = tap->ir_length; fields[i].num_bits = field_size; - uint8_t *v = malloc(DIV_ROUND_UP(field_size, 8)); + uint8_t *v = calloc(1, DIV_ROUND_UP(field_size, 8)); uint64_t value; retval = parse_u64(CMD_ARGV[i * 2 + 1], &value); diff --git a/src/target/arm_jtag.c b/src/target/arm_jtag.c index 9b73d4ea8..49aca3487 100644 --- a/src/target/arm_jtag.c +++ b/src/target/arm_jtag.c @@ -33,7 +33,7 @@ int arm_jtag_set_instr_inner(struct jtag_tap *tap, uint32_t new_instr, void *no_verify_capture, tap_state_t end_state) { struct scan_field field; - uint8_t t[4]; + uint8_t t[4] = { 0 }; field.num_bits = tap->ir_length; field.out_value = t; @@ -56,7 +56,7 @@ int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, ta { int retval = ERROR_OK; - uint8_t out_value[4]; + uint8_t out_value[4] = { 0 }; buf_set_u32(out_value, 0, jtag_info->scann_size, new_scan_chain); struct scan_field field = { .num_bits = jtag_info->scann_size, .out_value = out_value, }; diff --git a/src/target/avr32_jtag.c b/src/target/avr32_jtag.c index c17fbe7f0..6a4d4b3e7 100644 --- a/src/target/avr32_jtag.c +++ b/src/target/avr32_jtag.c @@ -35,7 +35,7 @@ static int avr32_jtag_set_instr(struct avr32_jtag *jtag_info, int new_instr) if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) { do { struct scan_field field; - uint8_t t[4]; + uint8_t t[4] = { 0 }; uint8_t ret[4]; field.num_bits = tap->ir_length; diff --git a/src/target/esirisc_jtag.c b/src/target/esirisc_jtag.c index 333a62225..700ae3a60 100644 --- a/src/target/esirisc_jtag.c +++ b/src/target/esirisc_jtag.c @@ -36,7 +36,7 @@ static void esirisc_jtag_set_instr(struct esirisc_jtag *jtag_info, uint32_t new_ if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) { struct scan_field field; - uint8_t t[4]; + uint8_t t[4] = { 0 }; field.num_bits = tap->ir_length; field.out_value = t; diff --git a/src/target/etb.c b/src/target/etb.c index 392c6ad7f..0c03c4dbe 100644 --- a/src/target/etb.c +++ b/src/target/etb.c @@ -176,13 +176,13 @@ static int etb_read_ram(struct etb *etb, uint32_t *data, int num_frames) fields[0].in_value = NULL; fields[1].num_bits = 7; - uint8_t temp1; + uint8_t temp1 = 0; fields[1].out_value = &temp1; buf_set_u32(&temp1, 0, 7, 4); fields[1].in_value = NULL; fields[2].num_bits = 1; - uint8_t temp2; + uint8_t temp2 = 0; fields[2].out_value = &temp2; buf_set_u32(&temp2, 0, 1, 0); fields[2].in_value = NULL; @@ -229,7 +229,7 @@ static int etb_read_reg_w_check(struct reg *reg, fields[0].check_mask = NULL; fields[1].num_bits = 7; - uint8_t temp1; + uint8_t temp1 = 0; fields[1].out_value = &temp1; buf_set_u32(&temp1, 0, 7, reg_addr); fields[1].in_value = NULL; @@ -237,7 +237,7 @@ static int etb_read_reg_w_check(struct reg *reg, fields[1].check_mask = NULL; fields[2].num_bits = 1; - uint8_t temp2; + uint8_t temp2 = 0; fields[2].out_value = &temp2; buf_set_u32(&temp2, 0, 1, 0); fields[2].in_value = NULL; @@ -310,13 +310,13 @@ static int etb_write_reg(struct reg *reg, uint32_t value) fields[0].in_value = NULL; fields[1].num_bits = 7; - uint8_t temp1; + uint8_t temp1 = 0; fields[1].out_value = &temp1; buf_set_u32(&temp1, 0, 7, reg_addr); fields[1].in_value = NULL; fields[2].num_bits = 1; - uint8_t temp2; + uint8_t temp2 = 0; fields[2].out_value = &temp2; buf_set_u32(&temp2, 0, 1, 1); fields[2].in_value = NULL; diff --git a/src/target/etm.c b/src/target/etm.c index d1cfe61f6..5218a9e48 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -533,7 +533,7 @@ static int etm_read_reg_w_check(struct reg *reg, fields[0].check_mask = NULL; fields[1].num_bits = 7; - uint8_t temp1; + uint8_t temp1 = 0; fields[1].out_value = &temp1; buf_set_u32(&temp1, 0, 7, reg_addr); fields[1].in_value = NULL; @@ -541,7 +541,7 @@ static int etm_read_reg_w_check(struct reg *reg, fields[1].check_mask = NULL; fields[2].num_bits = 1; - uint8_t temp2; + uint8_t temp2 = 0; fields[2].out_value = &temp2; buf_set_u32(&temp2, 0, 1, 0); fields[2].in_value = NULL; @@ -620,13 +620,13 @@ static int etm_write_reg(struct reg *reg, uint32_t value) fields[0].in_value = NULL; fields[1].num_bits = 7; - uint8_t tmp2; + uint8_t tmp2 = 0; fields[1].out_value = &tmp2; buf_set_u32(&tmp2, 0, 7, reg_addr); fields[1].in_value = NULL; fields[2].num_bits = 1; - uint8_t tmp3; + uint8_t tmp3 = 0; fields[2].out_value = &tmp3; buf_set_u32(&tmp3, 0, 1, 1); fields[2].in_value = NULL; diff --git a/src/target/ls1_sap.c b/src/target/ls1_sap.c index bc46ed4db..330042f00 100644 --- a/src/target/ls1_sap.c +++ b/src/target/ls1_sap.c @@ -113,7 +113,7 @@ static void ls1_sap_set_instr(struct jtag_tap *tap, uint32_t new_instr) static void ls1_sap_set_addr_high(struct jtag_tap *tap, uint16_t addr_high) { struct scan_field field; - uint8_t buf[2]; + uint8_t buf[2] = { 0 }; ls1_sap_set_instr(tap, 0x21); @@ -130,7 +130,7 @@ static void ls1_sap_memory_cmd(struct jtag_tap *tap, uint32_t address, int32_t size, bool rnw) { struct scan_field field; - uint8_t cmd[8]; + uint8_t cmd[8] = { 0 }; ls1_sap_set_instr(tap, 0x24); diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c index 6d35e211d..00bafd033 100644 --- a/src/target/mips_ejtag.c +++ b/src/target/mips_ejtag.c @@ -43,7 +43,7 @@ void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr) struct scan_field field; field.num_bits = tap->ir_length; - uint8_t t[4]; + uint8_t t[4] = { 0 }; field.out_value = t; buf_set_u32(t, 0, field.num_bits, new_instr); @@ -100,7 +100,7 @@ int mips_ejtag_drscan_64(struct mips_ejtag *ejtag_info, uint64_t *data) if (tap == NULL) return ERROR_FAIL; struct scan_field field; - uint8_t t[8], r[8]; + uint8_t t[8] = { 0 }, r[8]; int retval; field.num_bits = 64; @@ -130,7 +130,7 @@ void mips_ejtag_drscan_32_queued(struct mips_ejtag *ejtag_info, uint32_t data_ou struct scan_field field; field.num_bits = 32; - uint8_t scan_out[4]; + uint8_t scan_out[4] = { 0 }; field.out_value = scan_out; buf_set_u32(scan_out, 0, field.num_bits, data_out); diff --git a/src/target/openrisc/or1k_tap_vjtag.c b/src/target/openrisc/or1k_tap_vjtag.c index 607451a7c..db10f103b 100644 --- a/src/target/openrisc/or1k_tap_vjtag.c +++ b/src/target/openrisc/or1k_tap_vjtag.c @@ -149,7 +149,7 @@ static int or1k_tap_vjtag_init(struct or1k_jtag *jtag_info) * into the USER1 DR is sufficient to cover the most conservative case for m and n. */ - uint8_t t[4]; + uint8_t t[4] = { 0 }; struct scan_field field; struct jtag_tap *tap = jtag_info->tap; diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index eded86246..cb7b744da 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -280,7 +280,7 @@ static uint32_t dtmcontrol_scan(struct target *target, uint32_t out) { struct scan_field field; uint8_t in_value[4]; - uint8_t out_value[4]; + uint8_t out_value[4] = { 0 }; buf_set_u32(out_value, 0, 32, out); @@ -422,7 +422,7 @@ static dbus_status_t dbus_scan(struct target *target, uint16_t *address_in, { riscv011_info_t *info = get_info(target); uint8_t in[8] = {0}; - uint8_t out[8]; + uint8_t out[8] = {0}; struct scan_field field = { .num_bits = info->addrbits + DBUS_OP_SIZE + DBUS_DATA_SIZE, .out_value = out, diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 1e5c02764..66218b76e 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -402,7 +402,7 @@ static uint32_t dtmcontrol_scan(struct target *target, uint32_t out) { struct scan_field field; uint8_t in_value[4]; - uint8_t out_value[4]; + uint8_t out_value[4] = { 0 }; buf_set_u32(out_value, 0, 32, out); @@ -468,6 +468,7 @@ static dmi_status_t dmi_scan(struct target *target, uint32_t *address_in, } memset(in, 0, num_bytes); + memset(out, 0, num_bytes); assert(info->abits != 0); diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 8b5a361bb..1d6f66699 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -203,7 +203,7 @@ static uint32_t dtmcontrol_scan(struct target *target, uint32_t out) { struct scan_field field; uint8_t in_value[4]; - uint8_t out_value[4]; + uint8_t out_value[4] = { 0 }; buf_set_u32(out_value, 0, 32, out); @@ -540,7 +540,7 @@ int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint) return ERROR_FAIL; } - uint8_t buff[4]; + uint8_t buff[4] = { 0 }; buf_set_u32(buff, 0, breakpoint->length * CHAR_BIT, breakpoint->length == 4 ? ebreak() : ebreak_c()); int const retval = target_write_memory(target, breakpoint->address, 2, breakpoint->length / 2, buff); @@ -1047,7 +1047,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, /* Disable Interrupts before attempting to run the algorithm. */ uint64_t current_mstatus; - uint8_t mstatus_bytes[8]; + uint8_t mstatus_bytes[8] = { 0 }; LOG_DEBUG("Disabling Interrupts"); struct reg *reg_mstatus = register_get_by_name(target->reg_cache, @@ -1103,7 +1103,7 @@ static int riscv_run_algorithm(struct target *target, int num_mem_params, reg_mstatus->type->set(reg_mstatus, mstatus_bytes); /* Restore registers */ - uint8_t buf[8]; + uint8_t buf[8] = { 0 }; buf_set_u64(buf, 0, info->xlen[0], saved_pc); if (reg_pc->type->set(reg_pc, buf) != ERROR_OK) return ERROR_FAIL; diff --git a/src/target/xscale.c b/src/target/xscale.c index 3ef8922b5..e57996585 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -129,7 +129,7 @@ static const struct xscale_reg xscale_reg_arch_info[] = { /* convenience wrapper to access XScale specific registers */ static int xscale_set_reg_u32(struct reg *reg, uint32_t value) { - uint8_t buf[4]; + uint8_t buf[4] = { 0 }; buf_set_u32(buf, 0, 32, value); @@ -154,7 +154,7 @@ static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_s if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) { struct scan_field field; - uint8_t scratch[4]; + uint8_t scratch[4] = { 0 }; memset(&field, 0, sizeof field); field.num_bits = tap->ir_length; @@ -514,7 +514,7 @@ static int xscale_send(struct target *target, const uint8_t *buffer, int count, TAP_IDLE); static const uint8_t t0; - uint8_t t1[4]; + uint8_t t1[4] = { 0 }; static const uint8_t t2 = 1; struct scan_field fields[3] = { { .num_bits = 3, .out_value = &t0 }, @@ -645,8 +645,8 @@ static unsigned int parity(unsigned int v) static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8]) { struct xscale_common *xscale = target_to_xscale(target); - uint8_t packet[4]; - uint8_t cmd; + uint8_t packet[4] = { 0 }; + uint8_t cmd = 0; int word; struct scan_field fields[2]; @@ -699,8 +699,8 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8] static int xscale_invalidate_ic_line(struct target *target, uint32_t va) { struct xscale_common *xscale = target_to_xscale(target); - uint8_t packet[4]; - uint8_t cmd; + uint8_t packet[4] = { 0 }; + uint8_t cmd = 0; struct scan_field fields[2]; xscale_jtag_set_instr(target->tap, From 6bc0a77a6e1a1146c44785812595250857fc7307 Mon Sep 17 00:00:00 2001 From: luca vinci Date: Tue, 5 Nov 2019 08:45:04 +0100 Subject: [PATCH 175/354] bluenrg-x: added support for BlueNRG-LP device Extended bluenrg-x flash driver with BlueNRG-LP flash controller. Changes include: - register set for the flash controller - made software structure prone to support more easily future devices - updated target config file Change-Id: I2e2dc70db32cf98c62e3a43f2e44a4600a25ac5b Signed-off-by: luca vinci Reviewed-on: http://openocd.zylin.com/5343 Tested-by: jenkins Reviewed-by: Tomas Vanek --- contrib/loaders/flash/bluenrg-x/Makefile | 7 +- .../flash/bluenrg-x/bluenrg-2_write.inc | 18 ++ .../flash/bluenrg-x/bluenrg-lp_write.inc | 18 ++ .../loaders/flash/bluenrg-x/bluenrg-x_write.c | 26 +- .../flash/bluenrg-x/bluenrg-x_write.inc | 18 -- doc/openocd.texi | 6 +- src/flash/nor/bluenrg-x.c | 223 +++++++++++++----- tcl/board/steval-idb011v1.cfg | 3 + tcl/target/bluenrg-x.cfg | 40 ++-- 9 files changed, 258 insertions(+), 101 deletions(-) create mode 100644 contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc create mode 100644 contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc delete mode 100644 contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc create mode 100644 tcl/board/steval-idb011v1.cfg diff --git a/contrib/loaders/flash/bluenrg-x/Makefile b/contrib/loaders/flash/bluenrg-x/Makefile index 1a5cfc013..ce86e481a 100644 --- a/contrib/loaders/flash/bluenrg-x/Makefile +++ b/contrib/loaders/flash/bluenrg-x/Makefile @@ -8,15 +8,18 @@ OBJDUMP=$(CROSS_COMPILE)objdump CFLAGS = -c -mthumb -mcpu=cortex-m0 -O3 -g -all: bluenrg-x_write.inc +all:bluenrg-2_write.inc bluenrg-lp_write.inc .PHONY: clean .INTERMEDIATE: bluenrg-x_write.o -%.o: %.c +bluenrg-2_write.o: bluenrg-x_write.c $(CC) $(CFLAGS) -Wall -Wextra -Wa,-adhln=$*.lst $< -o $@ +bluenrg-lp_write.o: bluenrg-x_write.c + $(CC) $(CFLAGS) -D BLUENRG_LP -Wall -Wextra -Wa,-adhln=$*.lst $< -o $@ + %.bin: %.o $(OBJCOPY) -Obinary $< $@ diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc new file mode 100644 index 000000000..1ce4c860e --- /dev/null +++ b/contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc @@ -0,0 +1,18 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0x05,0x93,0x43,0x68,0x06,0x00,0x09,0x93,0x05,0x9b,0x07,0x91,0x06,0x92,0x34,0x4d, +0x34,0x4c,0x00,0x2b,0x5d,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0xfb,0xd0,0x33,0x68, +0x00,0x2b,0x56,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0x53,0xd9,0x73,0x68,0x07,0x9a, +0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x00,0x21,0x2b,0x4a,0x03,0x93,0x11,0x60,0x00,0x2b, +0x37,0xd0,0x2a,0x4a,0x06,0x9b,0x94,0x46,0x63,0x44,0x18,0x00,0x73,0x68,0x08,0x96, +0x04,0x93,0x1a,0x00,0x26,0x4b,0x99,0x46,0x26,0x4b,0x98,0x46,0x26,0x4b,0x9c,0x46, +0x26,0x4b,0x9b,0x46,0x26,0x4b,0x9a,0x46,0x01,0x23,0x91,0x68,0x17,0x68,0x01,0x91, +0xd1,0x68,0x56,0x68,0x02,0x91,0x3f,0x21,0x29,0x60,0x81,0x03,0x09,0x0c,0x21,0x60, +0x49,0x46,0x0f,0x60,0x47,0x46,0x3e,0x60,0x66,0x46,0x01,0x99,0x31,0x60,0x5e,0x46, +0x02,0x99,0x31,0x60,0x51,0x46,0xcc,0x26,0x0e,0x60,0x29,0x68,0x0b,0x42,0xfc,0xd0, +0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30,0x51,0x1a,0x8e,0x42,0xdd,0xd8,0x08,0x9e, +0x72,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46,0x63,0x44,0x06,0x93,0x07,0x9a,0x73,0x68, +0x9a,0x42,0x01,0xd8,0x09,0x9b,0x73,0x60,0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93, +0xa1,0xd1,0x00,0xbe,0x33,0x68,0x72,0x68,0x9b,0x1a,0xaa,0xd5,0x9b,0xe7,0xc0,0x46, +0x10,0x00,0x10,0x40,0x18,0x00,0x10,0x40,0x0c,0x00,0x10,0x40,0x00,0x00,0xfc,0xef, +0x40,0x00,0x10,0x40,0x44,0x00,0x10,0x40,0x48,0x00,0x10,0x40,0x4c,0x00,0x10,0x40, +0x00,0x00,0x10,0x40, diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc new file mode 100644 index 000000000..cc9b2a174 --- /dev/null +++ b/contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc @@ -0,0 +1,18 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0x05,0x93,0x43,0x68,0x06,0x00,0x09,0x93,0x05,0x9b,0x07,0x91,0x06,0x92,0x34,0x4d, +0x34,0x4c,0x00,0x2b,0x5d,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0xfb,0xd0,0x33,0x68, +0x00,0x2b,0x56,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0x53,0xd9,0x73,0x68,0x07,0x9a, +0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x00,0x21,0x2b,0x4a,0x03,0x93,0x11,0x60,0x00,0x2b, +0x37,0xd0,0x2a,0x4a,0x06,0x9b,0x94,0x46,0x63,0x44,0x18,0x00,0x73,0x68,0x08,0x96, +0x04,0x93,0x1a,0x00,0x26,0x4b,0x99,0x46,0x26,0x4b,0x98,0x46,0x26,0x4b,0x9c,0x46, +0x26,0x4b,0x9b,0x46,0x26,0x4b,0x9a,0x46,0x01,0x23,0x91,0x68,0x17,0x68,0x01,0x91, +0xd1,0x68,0x56,0x68,0x02,0x91,0x3f,0x21,0x29,0x60,0x81,0x03,0x09,0x0c,0x21,0x60, +0x49,0x46,0x0f,0x60,0x47,0x46,0x3e,0x60,0x66,0x46,0x01,0x99,0x31,0x60,0x5e,0x46, +0x02,0x99,0x31,0x60,0x51,0x46,0xcc,0x26,0x0e,0x60,0x29,0x68,0x0b,0x42,0xfc,0xd0, +0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30,0x51,0x1a,0x8e,0x42,0xdd,0xd8,0x08,0x9e, +0x72,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46,0x63,0x44,0x06,0x93,0x07,0x9a,0x73,0x68, +0x9a,0x42,0x01,0xd8,0x09,0x9b,0x73,0x60,0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93, +0xa1,0xd1,0x00,0xbe,0x33,0x68,0x72,0x68,0x9b,0x1a,0xaa,0xd5,0x9b,0xe7,0xc0,0x46, +0x10,0x10,0x00,0x40,0x18,0x10,0x00,0x40,0x0c,0x10,0x00,0x40,0x00,0x00,0xfc,0xef, +0x40,0x10,0x00,0x40,0x44,0x10,0x00,0x40,0x48,0x10,0x00,0x40,0x4c,0x10,0x00,0x40, +0x00,0x10,0x00,0x40, diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c index 3dd17b2fc..695f9145a 100644 --- a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c +++ b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c @@ -14,6 +14,21 @@ #define ERR_VERIFY_FAILED 7 /* Flash Controller defines ---------------------------------------------------*/ +#ifdef BLUENRG_LP +#define FLASH_REG_COMMAND ((volatile uint32_t *)0x40001000) +#define FLASH_REG_CONFIG ((volatile uint32_t *)0x40001004) +#define FLASH_REG_IRQSTAT ((volatile uint32_t *)0x40001008) +#define FLASH_REG_IRQMASK ((volatile uint32_t *)0x4000100C) +#define FLASH_REG_IRQRAW ((volatile uint32_t *)0x40001010) +#define FLASH_REG_ADDRESS ((volatile uint32_t *)0x40001018) +#define FLASH_REG_UNLOCKM ((volatile uint32_t *)0x4000101C) +#define FLASH_REG_UNLOCKL ((volatile uint32_t *)0x40001020) +#define FLASH_REG_DATA0 ((volatile uint32_t *)0x40001040) +#define FLASH_REG_DATA1 ((volatile uint32_t *)0x40001044) +#define FLASH_REG_DATA2 ((volatile uint32_t *)0x40001048) +#define FLASH_REG_DATA3 ((volatile uint32_t *)0x4000104C) +#define FLASH_SIZE_REG 0x40001014 +#else #define FLASH_REG_COMMAND ((volatile uint32_t *)0x40100000) #define FLASH_REG_CONFIG ((volatile uint32_t *)0x40100004) #define FLASH_REG_IRQSTAT ((volatile uint32_t *)0x40100008) @@ -22,11 +37,12 @@ #define FLASH_REG_ADDRESS ((volatile uint32_t *)0x40100018) #define FLASH_REG_UNLOCKM ((volatile uint32_t *)0x4010001C) #define FLASH_REG_UNLOCKL ((volatile uint32_t *)0x40100020) -#define FLASH_REG_DATA0 ((volatile uint32_t *)0x40100040) -#define FLASH_REG_DATA1 ((volatile uint32_t *)0x40100044) -#define FLASH_REG_DATA2 ((volatile uint32_t *)0x40100048) -#define FLASH_REG_DATA3 ((volatile uint32_t *)0x4010004C) +#define FLASH_REG_DATA0 ((volatile uint32_t *)0x40100040) +#define FLASH_REG_DATA1 ((volatile uint32_t *)0x40100044) +#define FLASH_REG_DATA2 ((volatile uint32_t *)0x40100048) +#define FLASH_REG_DATA3 ((volatile uint32_t *)0x4010004C) #define FLASH_SIZE_REG 0x40100014 +#endif #define MFB_MASS_ERASE 0x01 #define MFB_PAGE_ERASE 0x02 @@ -70,7 +86,7 @@ static inline __attribute__((always_inline)) uint32_t flashWrite(uint32_t addres /* Clear the IRQ flags */ *FLASH_REG_IRQRAW = 0x0000003F; /* Load the flash address to write */ - *FLASH_REG_ADDRESS = (uint16_t)((address + index) >> 2); + *FLASH_REG_ADDRESS = (uint16_t)((address + index - MFB_BOTTOM) >> 2); /* Prepare and load the data to flash */ *FLASH_REG_DATA0 = flash_word[0]; *FLASH_REG_DATA1 = flash_word[1]; diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc deleted file mode 100644 index 47f331228..000000000 --- a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc +++ /dev/null @@ -1,18 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x05,0x93,0x43,0x68,0x05,0x00,0x07,0x93,0x05,0x9b,0x06,0x91,0x03,0x92,0x35,0x4c, -0x00,0x2b,0x5c,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0xfb,0xd0,0x2b,0x68,0x00,0x2b, -0x55,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0x52,0xd9,0x6b,0x68,0x06,0x9a,0xd3,0x1a, -0x09,0x93,0x09,0x9b,0x0f,0x2b,0xed,0xdd,0x00,0x21,0x09,0x9b,0x04,0x93,0x1a,0x1e, -0x29,0x4b,0x19,0x60,0x32,0xd0,0x29,0x4b,0x00,0x20,0x98,0x46,0x28,0x4b,0x6a,0x68, -0x9c,0x46,0x28,0x4b,0x28,0x4e,0x9b,0x46,0x28,0x4b,0x9a,0x46,0x28,0x4b,0x99,0x46, -0x01,0x23,0x51,0x68,0x17,0x68,0x00,0x91,0x91,0x68,0x01,0x91,0xd1,0x68,0x02,0x91, -0x3f,0x21,0x21,0x60,0x03,0x99,0x09,0x18,0x89,0x03,0x09,0x0c,0x31,0x60,0x41,0x46, -0x0f,0x60,0x67,0x46,0x00,0x99,0x39,0x60,0x5f,0x46,0x01,0x99,0x39,0x60,0x57,0x46, -0x02,0x99,0x39,0x60,0x49,0x46,0xcc,0x27,0x0f,0x60,0x21,0x68,0x0b,0x42,0xfc,0xd0, -0x04,0x99,0x10,0x32,0x10,0x30,0x6a,0x60,0x81,0x42,0xda,0xd8,0x03,0x9a,0x09,0x9b, -0x94,0x46,0x9c,0x44,0x63,0x46,0x06,0x9a,0x03,0x93,0x6b,0x68,0x9a,0x42,0x01,0xd8, -0x07,0x9b,0x6b,0x60,0x05,0x9a,0x09,0x9b,0xd3,0x1a,0x05,0x93,0xa2,0xd1,0x00,0xbe, -0x2b,0x68,0x6a,0x68,0x9b,0x1a,0x09,0x93,0x09,0x9b,0x00,0x2b,0xa9,0xda,0x00,0x23, -0x09,0x93,0xa6,0xe7,0x10,0x00,0x10,0x40,0x0c,0x00,0x10,0x40,0x40,0x00,0x10,0x40, -0x44,0x00,0x10,0x40,0x48,0x00,0x10,0x40,0x18,0x00,0x10,0x40,0x4c,0x00,0x10,0x40, -0x00,0x00,0x10,0x40, diff --git a/doc/openocd.texi b/doc/openocd.texi index d059cfae2..8bb4df685 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5830,7 +5830,7 @@ The AVR 8-bit microcontrollers from Atmel integrate flash memory. @end deffn @deffn {Flash Driver} bluenrg-x -STMicroelectronics BlueNRG-1 and BlueNRG-2 Bluetooth low energy wireless system-on-chip. They include ARM Cortex-M0 core and internal flash memory. +STMicroelectronics BlueNRG-1, BlueNRG-2 and BlueNRG-LP Bluetooth low energy wireless system-on-chip. They include ARM Cortex-M0/M0+ core and internal flash memory. The driver automatically recognizes these chips using the chip identification registers, and autoconfigures itself. @@ -5849,6 +5849,10 @@ flash erase_sector 0 0 79 # It will perform a mass erase on BlueNRG-1 flash erase_sector 0 0 127 # It will perform a mass erase on BlueNRG-2 @end example +@example +flash erase_sector 0 0 127 # It will perform a mass erase on BlueNRG-LP +@end example + Triggering a mass erase is also useful when users want to disable readout protection. @end deffn diff --git a/src/flash/nor/bluenrg-x.c b/src/flash/nor/bluenrg-x.c index f6a249273..79821168e 100644 --- a/src/flash/nor/bluenrg-x.c +++ b/src/flash/nor/bluenrg-x.c @@ -25,16 +25,20 @@ #include #include "imp.h" -#define FLASH_SIZE_REG (0x40100014) -#define DIE_ID_REG (0x4090001C) -#define JTAG_IDCODE_REG (0x40900028) #define BLUENRG2_IDCODE (0x0200A041) -#define FLASH_BASE (0x10040000) -#define FLASH_PAGE_SIZE (2048) -#define FLASH_REG_COMMAND (0x40100000) -#define FLASH_REG_IRQRAW (0x40100010) -#define FLASH_REG_ADDRESS (0x40100018) -#define FLASH_REG_DATA (0x40100040) +#define BLUENRGLP_IDCODE (0x0201E041) +#define BLUENRG2_JTAG_REG (flash_priv_data_2.jtag_idcode_reg) +#define BLUENRGLP_JTAG_REG (flash_priv_data_lp.jtag_idcode_reg) + +#define FLASH_SIZE_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_size_reg) +#define DIE_ID_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->die_id_reg) +#define JTAG_IDCODE_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->jtag_idcode_reg) +#define FLASH_BASE(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_base) +#define FLASH_PAGE_SIZE(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_page_size) +#define FLASH_REG_COMMAND(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_command) +#define FLASH_REG_IRQRAW(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_irqraw) +#define FLASH_REG_ADDRESS(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_address) +#define FLASH_REG_DATA(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_data) #define FLASH_CMD_ERASE_PAGE 0x11 #define FLASH_CMD_MASSERASE 0x22 #define FLASH_CMD_WRITE 0x33 @@ -42,12 +46,91 @@ #define FLASH_INT_CMDDONE 0x01 #define FLASH_WORD_LEN 4 +/* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and + * hints how to generate the data! + */ +static const uint8_t bluenrgx_flash_write_code_2[] = { +#include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc" + }; + +static const uint8_t bluenrgx_flash_write_code_lp[] = { +#include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc" + }; + +struct flash_ctrl_priv_data { + uint32_t flash_size_reg; + uint32_t die_id_reg; + uint32_t jtag_idcode_reg; + uint32_t flash_base; + uint32_t flash_page_size; + uint32_t flash_reg_command; + uint32_t flash_reg_irqraw; + uint32_t flash_reg_address; + uint32_t flash_reg_data; + uint32_t jtag_idcode; + char *part_name; + const uint8_t *flash_write_code; + uint32_t flash_write_code_size; +}; + +const struct flash_ctrl_priv_data flash_priv_data_1 = { + .flash_size_reg = 0x40100014, + .die_id_reg = 0x4090001C, + .jtag_idcode_reg = 0x40900028, + .flash_base = 0x10040000, + .flash_page_size = 2048, + .flash_reg_command = 0x40100000, + .flash_reg_irqraw = 0x40100010, + .flash_reg_address = 0x40100018, + .flash_reg_data = 0x40100040, + .jtag_idcode = 0x00000000, + .part_name = "BLUENRG-1", + .flash_write_code = bluenrgx_flash_write_code_2, + .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2), +}; + +const struct flash_ctrl_priv_data flash_priv_data_2 = { + .flash_size_reg = 0x40100014, + .die_id_reg = 0x4090001C, + .jtag_idcode_reg = 0x40900028, + .flash_base = 0x10040000, + .flash_page_size = 2048, + .flash_reg_command = 0x40100000, + .flash_reg_irqraw = 0x40100010, + .flash_reg_address = 0x40100018, + .flash_reg_data = 0x40100040, + .jtag_idcode = BLUENRG2_IDCODE, + .part_name = "BLUENRG-2", + .flash_write_code = bluenrgx_flash_write_code_2, + .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2), +}; + +const struct flash_ctrl_priv_data flash_priv_data_lp = { + .flash_size_reg = 0x40001014, + .die_id_reg = 0x40000000, + .jtag_idcode_reg = 0x40000004, + .flash_base = 0x10040000, + .flash_page_size = 2048, + .flash_reg_command = 0x40001000, + .flash_reg_irqraw = 0x40001010, + .flash_reg_address = 0x40001018, + .flash_reg_data = 0x40001040, + .jtag_idcode = BLUENRGLP_IDCODE, + .part_name = "BLUENRG-LP", + .flash_write_code = bluenrgx_flash_write_code_lp, + .flash_write_code_size = sizeof(bluenrgx_flash_write_code_lp), +}; + struct bluenrgx_flash_bank { int probed; - uint32_t idcode; uint32_t die_id; + const struct flash_ctrl_priv_data *flash_ptr; + const uint8_t *flash_write_code; + uint32_t flash_write_code_size; }; +const struct flash_ctrl_priv_data *flash_ctrl[] = {&flash_priv_data_1, &flash_priv_data_2, &flash_priv_data_lp}; + static int bluenrgx_protect_check(struct flash_bank *bank) { /* Nothing to do. Protection is only handled in SW. */ @@ -103,24 +186,25 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last) if (mass_erase) { command = FLASH_CMD_MASSERASE; address = bank->base; - if (target_write_u32(target, FLASH_REG_IRQRAW, 0x3f) != ERROR_OK) { + if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } - if (target_write_u32(target, FLASH_REG_ADDRESS, address >> 2) != ERROR_OK) { + if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info), + (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } - if (target_write_u32(target, FLASH_REG_COMMAND, command) != ERROR_OK) { + if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } for (int i = 0; i < 100; i++) { uint32_t value; - if (target_read_u32(target, FLASH_REG_IRQRAW, &value)) { + if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } @@ -135,26 +219,28 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last) } else { command = FLASH_CMD_ERASE_PAGE; for (int i = first; i <= last; i++) { - address = bank->base+i*FLASH_PAGE_SIZE; + address = bank->base+i*FLASH_PAGE_SIZE(bluenrgx_info); + LOG_DEBUG("address = %08x, index = %d", address, i); - if (target_write_u32(target, FLASH_REG_IRQRAW, 0x3f) != ERROR_OK) { + if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } - if (target_write_u32(target, FLASH_REG_ADDRESS, address >> 2) != ERROR_OK) { + if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info), + (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } - if (target_write_u32(target, FLASH_REG_COMMAND, command) != ERROR_OK) { + if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) { LOG_ERROR("Failed"); return ERROR_FAIL; } for (int j = 0; j < 100; j++) { uint32_t value; - if (target_read_u32(target, FLASH_REG_IRQRAW, &value)) { + if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } @@ -182,11 +268,14 @@ static int bluenrgx_protect(struct flash_bank *bank, int set, int first, int las bank->sectors[sector].is_protected = set; return ERROR_OK; } -static int bluenrgx_write_word(struct target *target, uint32_t address_base, uint8_t *values, uint32_t count) + +static int bluenrgx_write_word(struct flash_bank *bank, uint32_t address_base, uint8_t *values, uint32_t count) { int retval = ERROR_OK; + struct target *target = bank->target; + struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; - retval = target_write_u32(target, FLASH_REG_IRQRAW, 0x3f); + retval = target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f); if (retval != ERROR_OK) { LOG_ERROR("Register write failed, error code: %d", retval); return retval; @@ -195,19 +284,21 @@ static int bluenrgx_write_word(struct target *target, uint32_t address_base, uin for (uint32_t i = 0; i < count; i++) { uint32_t address = address_base + i * FLASH_WORD_LEN; - retval = target_write_u32(target, FLASH_REG_ADDRESS, address >> 2); + retval = target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info), + (address - FLASH_BASE(bluenrgx_info)) >> 2); if (retval != ERROR_OK) { LOG_ERROR("Register write failed, error code: %d", retval); return retval; } - retval = target_write_buffer(target, FLASH_REG_DATA, FLASH_WORD_LEN, values + i * FLASH_WORD_LEN); + retval = target_write_buffer(target, FLASH_REG_DATA(bluenrgx_info), + FLASH_WORD_LEN, values + i * FLASH_WORD_LEN); if (retval != ERROR_OK) { LOG_ERROR("Register write failed, error code: %d", retval); return retval; } - retval = target_write_u32(target, FLASH_REG_COMMAND, FLASH_CMD_WRITE); + retval = target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), FLASH_CMD_WRITE); if (retval != ERROR_OK) { LOG_ERROR("Register write failed, error code: %d", retval); return retval; @@ -215,7 +306,7 @@ static int bluenrgx_write_word(struct target *target, uint32_t address_base, uin for (int j = 0; j < 100; j++) { uint32_t reg_value; - retval = target_read_u32(target, FLASH_REG_IRQRAW, ®_value); + retval = target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), ®_value); if (retval != ERROR_OK) { LOG_ERROR("Register read failed, error code: %d", retval); @@ -234,9 +325,10 @@ static int bluenrgx_write_word(struct target *target, uint32_t address_base, uin return retval; } -static int bluenrgx_write_bytes(struct target *target, uint32_t address_base, uint8_t *buffer, uint32_t count) +static int bluenrgx_write_bytes(struct flash_bank *bank, uint32_t address_base, uint8_t *buffer, uint32_t count) { int retval = ERROR_OK; + struct target *target = bank->target; uint8_t *new_buffer = NULL; uint32_t pre_bytes = 0, post_bytes = 0, pre_word, post_word, pre_address, post_address; @@ -295,7 +387,7 @@ static int bluenrgx_write_bytes(struct target *target, uint32_t address_base, ui buffer = new_buffer; } - retval = bluenrgx_write_word(target, address_base - pre_bytes, buffer, count/4); + retval = bluenrgx_write_word(bank, address_base - pre_bytes, buffer, count/4); if (new_buffer) free(new_buffer); @@ -306,6 +398,7 @@ static int bluenrgx_write_bytes(struct target *target, uint32_t address_base, ui static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { + struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; struct target *target = bank->target; uint32_t buffer_size = 16384 + 8; struct working_area *write_algorithm; @@ -318,12 +411,9 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t pre_size = 0, fast_size = 0, post_size = 0; uint32_t pre_offset = 0, fast_offset = 0, post_offset = 0; - /* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and - * hints how to generate the data! - */ - static const uint8_t bluenrgx_flash_write_code[] = { -#include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc" - }; + /* check preconditions */ + if (bluenrgx_info->probed == 0) + return ERROR_FLASH_BANK_NOT_PROBED; if ((offset + count) > bank->size) { LOG_ERROR("Requested write past beyond of flash size: (offset+count) = %d, size=%d", @@ -350,7 +440,7 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, LOG_DEBUG("post_size = %08x, post_offset=%08x", post_size, post_offset); /* Program initial chunk not 16 bytes aligned */ - retval = bluenrgx_write_bytes(target, bank->base+pre_offset, (uint8_t *) buffer, pre_size); + retval = bluenrgx_write_bytes(bank, bank->base+pre_offset, (uint8_t *) buffer, pre_size); if (retval) { LOG_ERROR("bluenrgx_write_bytes failed %d", retval); return ERROR_FAIL; @@ -359,15 +449,15 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, /* Program chunk 16 bytes aligned in fast mode */ if (fast_size) { - if (target_alloc_working_area(target, sizeof(bluenrgx_flash_write_code), - &write_algorithm) != ERROR_OK) { + if (target_alloc_working_area(target, bluenrgx_info->flash_write_code_size, + &write_algorithm) != ERROR_OK) { LOG_WARNING("no working area available, can't do block memory writes"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } retval = target_write_buffer(target, write_algorithm->address, - sizeof(bluenrgx_flash_write_code), - bluenrgx_flash_write_code); + bluenrgx_info->flash_write_code_size, + bluenrgx_info->flash_write_code); if (retval != ERROR_OK) return retval; @@ -379,7 +469,7 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, /* Stack pointer area */ if (target_alloc_working_area(target, 64, - &write_algorithm_sp) != ERROR_OK) { + &write_algorithm_sp) != ERROR_OK) { LOG_DEBUG("no working area for write code stack pointer"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } @@ -458,7 +548,8 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, } /* Program chunk at end, not addressable by fast burst write algorithm */ - retval = bluenrgx_write_bytes(target, bank->base+post_offset, (uint8_t *) (buffer+pre_size+fast_size), post_size); + retval = bluenrgx_write_bytes(bank, bank->base+post_offset, + (uint8_t *) (buffer+pre_size+fast_size), post_size); if (retval) { LOG_ERROR("bluenrgx_write_bytes failed %d", retval); return ERROR_FAIL; @@ -471,32 +562,54 @@ static int bluenrgx_probe(struct flash_bank *bank) struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; uint32_t idcode, size_info, die_id; int i; - int retval = target_read_u32(bank->target, JTAG_IDCODE_REG, &idcode); - if (retval != ERROR_OK) - return retval; - retval = target_read_u32(bank->target, FLASH_SIZE_REG, &size_info); + int retval = target_read_u32(bank->target, BLUENRGLP_JTAG_REG, &idcode); + if (retval != ERROR_OK) return retval; - retval = target_read_u32(bank->target, DIE_ID_REG, &die_id); + if (idcode != BLUENRGLP_IDCODE) { + retval = target_read_u32(bank->target, BLUENRG2_JTAG_REG, &idcode); + if (retval != ERROR_OK) + return retval; + } + + /* Default device is BlueNRG-1 */ + bluenrgx_info->flash_ptr = &flash_priv_data_1; + bluenrgx_info->flash_write_code = flash_priv_data_1.flash_write_code; + bluenrgx_info->flash_write_code_size = flash_priv_data_1.flash_write_code_size; + + for (i = 0; i < (int)(sizeof(flash_ctrl)/sizeof(*flash_ctrl)); i++) { + if (idcode == (*flash_ctrl[i]).jtag_idcode) { + bluenrgx_info->flash_ptr = flash_ctrl[i]; + bluenrgx_info->flash_write_code = (*flash_ctrl[i]).flash_write_code; + bluenrgx_info->flash_write_code_size = (*flash_ctrl[i]).flash_write_code_size; + break; + } + } + + retval = target_read_u32(bank->target, FLASH_SIZE_REG(bluenrgx_info), &size_info); if (retval != ERROR_OK) return retval; - bank->size = (size_info + 1) * 4; - bank->base = FLASH_BASE; - bank->num_sectors = bank->size/FLASH_PAGE_SIZE; + retval = target_read_u32(bank->target, DIE_ID_REG(bluenrgx_info), &die_id); + if (retval != ERROR_OK) + return retval; + + bank->size = (size_info + 1) * FLASH_WORD_LEN; + bank->base = FLASH_BASE(bluenrgx_info); + bank->num_sectors = bank->size/FLASH_PAGE_SIZE(bluenrgx_info); bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector) * bank->num_sectors); for (i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = i * FLASH_PAGE_SIZE; - bank->sectors[i].size = FLASH_PAGE_SIZE; + bank->sectors[i].offset = i * FLASH_PAGE_SIZE(bluenrgx_info); + bank->sectors[i].size = FLASH_PAGE_SIZE(bluenrgx_info); bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 0; } bluenrgx_info->probed = 1; bluenrgx_info->die_id = die_id; - bluenrgx_info->idcode = idcode; + return ERROR_OK; } @@ -515,7 +628,6 @@ static int bluenrgx_get_info(struct flash_bank *bank, char *buf, int buf_size) { struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; int mask_number, cut_number; - char *part_name; if (!bluenrgx_info->probed) { int retval = bluenrgx_probe(bank); @@ -526,16 +638,11 @@ static int bluenrgx_get_info(struct flash_bank *bank, char *buf, int buf_size) } } - if (bluenrgx_info->idcode == BLUENRG2_IDCODE) - part_name = "BLUENRG-2"; - else - part_name = "BLUENRG-1"; - mask_number = (bluenrgx_info->die_id >> 4) & 0xF; cut_number = bluenrgx_info->die_id & 0xF; snprintf(buf, buf_size, - "%s - Rev: %d.%d", part_name, mask_number, cut_number); + "%s - Rev: %d.%d", bluenrgx_info->flash_ptr->part_name, mask_number, cut_number); return ERROR_OK; } diff --git a/tcl/board/steval-idb011v1.cfg b/tcl/board/steval-idb011v1.cfg new file mode 100644 index 000000000..5988c6386 --- /dev/null +++ b/tcl/board/steval-idb011v1.cfg @@ -0,0 +1,3 @@ +# This is an evaluation board with a single BlueNRG-LP chip. +set CHIPNAME bluenrg-lp +source [find target/bluenrg-x.cfg] diff --git a/tcl/target/bluenrg-x.cfg b/tcl/target/bluenrg-x.cfg index 109db1708..691bbbf83 100644 --- a/tcl/target/bluenrg-x.cfg +++ b/tcl/target/bluenrg-x.cfg @@ -1,8 +1,9 @@ # -# bluenrg-1/2 devices support only SWD transports. +# bluenrg-1/2 and bluenrg-lp devices support only SWD transports. # source [find target/swj-dp.tcl] +source [find mem_helper.tcl] if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME @@ -53,22 +54,27 @@ if {![using_hla]} { } $_TARGETNAME configure -event halted { - global WDOG_VALUE - global WDOG_VALUE_SET - # Stop watchdog during halt, if enabled - mem2array value 32 0x40700008 1 - set WDOG_VALUE [expr ($value(0))] - if [expr ($value(0) & (1 << 1))] { - set WDOG_VALUE_SET 1 - mww 0x40700008 [expr ($value(0) & 0xFFFFFFFD)] - } + global WDOG_VALUE + global WDOG_VALUE_SET + set _JTAG_IDCODE [mrw 0x40000004] + if {$_JTAG_IDCODE != 0x0201E041} { + # Stop watchdog during halt, if enabled. Only Bluenrg-1/2 + set WDOG_VALUE [mrw 0x40700008] + if [expr ($WDOG_VALUE & (1 << 1))] { + set WDOG_VALUE_SET 1 + mww 0x40700008 [expr ($WDOG_VALUE & 0xFFFFFFFD)] + } + } } $_TARGETNAME configure -event resumed { - global WDOG_VALUE - global WDOG_VALUE_SET - if [expr $WDOG_VALUE_SET] { - # Restore watchdog enable value after resume - mww 0x40700008 $WDOG_VALUE - set WDOG_VALUE_SET 0 - } + global WDOG_VALUE + global WDOG_VALUE_SET + set _JTAG_IDCODE [mrw 0x40000004] + if {$_JTAG_IDCODE != 0x0201E041} { + if [expr $WDOG_VALUE_SET] { + # Restore watchdog enable value after resume. Only Bluenrg-1/2 + mww 0x40700008 $WDOG_VALUE + set WDOG_VALUE_SET 0 + } + } } From e9932ef23d4af8466e724b7603549778fb93c294 Mon Sep 17 00:00:00 2001 From: luca vinci Date: Wed, 8 Jan 2020 10:15:40 +0100 Subject: [PATCH 176/354] bluenrg-x: simplyfied the driver Adopted only fast algorithm for flash programming: - write_word and write_byte methods have been removed. - start and end write alignments have been defined. Moved flash controller registers offsets in a common file shared with the flash algorithm. - the flash base address is passed to the flash algorithm as a parameter. Removed unused functions Change-Id: I80aeab3994e477044bbcf02e66d9525dae0cb491 Signed-off-by: luca vinci Reviewed-on: http://openocd.zylin.com/5393 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Michele Sardo --- contrib/loaders/flash/bluenrg-x/Makefile | 7 +- .../flash/bluenrg-x/bluenrg-2_write.inc | 18 - .../flash/bluenrg-x/bluenrg-lp_write.inc | 18 - .../loaders/flash/bluenrg-x/bluenrg-x_write.c | 77 +-- .../flash/bluenrg-x/bluenrg-x_write.inc | 17 + doc/openocd.texi | 10 +- src/flash/nor/Makefile.am | 1 + src/flash/nor/bluenrg-x.c | 464 +++++------------- src/flash/nor/bluenrg-x.h | 45 ++ tcl/target/bluenrg-x.cfg | 8 +- 10 files changed, 220 insertions(+), 445 deletions(-) delete mode 100644 contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc delete mode 100644 contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc create mode 100644 contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc create mode 100644 src/flash/nor/bluenrg-x.h diff --git a/contrib/loaders/flash/bluenrg-x/Makefile b/contrib/loaders/flash/bluenrg-x/Makefile index ce86e481a..1a5cfc013 100644 --- a/contrib/loaders/flash/bluenrg-x/Makefile +++ b/contrib/loaders/flash/bluenrg-x/Makefile @@ -8,18 +8,15 @@ OBJDUMP=$(CROSS_COMPILE)objdump CFLAGS = -c -mthumb -mcpu=cortex-m0 -O3 -g -all:bluenrg-2_write.inc bluenrg-lp_write.inc +all: bluenrg-x_write.inc .PHONY: clean .INTERMEDIATE: bluenrg-x_write.o -bluenrg-2_write.o: bluenrg-x_write.c +%.o: %.c $(CC) $(CFLAGS) -Wall -Wextra -Wa,-adhln=$*.lst $< -o $@ -bluenrg-lp_write.o: bluenrg-x_write.c - $(CC) $(CFLAGS) -D BLUENRG_LP -Wall -Wextra -Wa,-adhln=$*.lst $< -o $@ - %.bin: %.o $(OBJCOPY) -Obinary $< $@ diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc deleted file mode 100644 index 1ce4c860e..000000000 --- a/contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc +++ /dev/null @@ -1,18 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x05,0x93,0x43,0x68,0x06,0x00,0x09,0x93,0x05,0x9b,0x07,0x91,0x06,0x92,0x34,0x4d, -0x34,0x4c,0x00,0x2b,0x5d,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0xfb,0xd0,0x33,0x68, -0x00,0x2b,0x56,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0x53,0xd9,0x73,0x68,0x07,0x9a, -0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x00,0x21,0x2b,0x4a,0x03,0x93,0x11,0x60,0x00,0x2b, -0x37,0xd0,0x2a,0x4a,0x06,0x9b,0x94,0x46,0x63,0x44,0x18,0x00,0x73,0x68,0x08,0x96, -0x04,0x93,0x1a,0x00,0x26,0x4b,0x99,0x46,0x26,0x4b,0x98,0x46,0x26,0x4b,0x9c,0x46, -0x26,0x4b,0x9b,0x46,0x26,0x4b,0x9a,0x46,0x01,0x23,0x91,0x68,0x17,0x68,0x01,0x91, -0xd1,0x68,0x56,0x68,0x02,0x91,0x3f,0x21,0x29,0x60,0x81,0x03,0x09,0x0c,0x21,0x60, -0x49,0x46,0x0f,0x60,0x47,0x46,0x3e,0x60,0x66,0x46,0x01,0x99,0x31,0x60,0x5e,0x46, -0x02,0x99,0x31,0x60,0x51,0x46,0xcc,0x26,0x0e,0x60,0x29,0x68,0x0b,0x42,0xfc,0xd0, -0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30,0x51,0x1a,0x8e,0x42,0xdd,0xd8,0x08,0x9e, -0x72,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46,0x63,0x44,0x06,0x93,0x07,0x9a,0x73,0x68, -0x9a,0x42,0x01,0xd8,0x09,0x9b,0x73,0x60,0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93, -0xa1,0xd1,0x00,0xbe,0x33,0x68,0x72,0x68,0x9b,0x1a,0xaa,0xd5,0x9b,0xe7,0xc0,0x46, -0x10,0x00,0x10,0x40,0x18,0x00,0x10,0x40,0x0c,0x00,0x10,0x40,0x00,0x00,0xfc,0xef, -0x40,0x00,0x10,0x40,0x44,0x00,0x10,0x40,0x48,0x00,0x10,0x40,0x4c,0x00,0x10,0x40, -0x00,0x00,0x10,0x40, diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc deleted file mode 100644 index cc9b2a174..000000000 --- a/contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc +++ /dev/null @@ -1,18 +0,0 @@ -/* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x05,0x93,0x43,0x68,0x06,0x00,0x09,0x93,0x05,0x9b,0x07,0x91,0x06,0x92,0x34,0x4d, -0x34,0x4c,0x00,0x2b,0x5d,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0xfb,0xd0,0x33,0x68, -0x00,0x2b,0x56,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0x53,0xd9,0x73,0x68,0x07,0x9a, -0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x00,0x21,0x2b,0x4a,0x03,0x93,0x11,0x60,0x00,0x2b, -0x37,0xd0,0x2a,0x4a,0x06,0x9b,0x94,0x46,0x63,0x44,0x18,0x00,0x73,0x68,0x08,0x96, -0x04,0x93,0x1a,0x00,0x26,0x4b,0x99,0x46,0x26,0x4b,0x98,0x46,0x26,0x4b,0x9c,0x46, -0x26,0x4b,0x9b,0x46,0x26,0x4b,0x9a,0x46,0x01,0x23,0x91,0x68,0x17,0x68,0x01,0x91, -0xd1,0x68,0x56,0x68,0x02,0x91,0x3f,0x21,0x29,0x60,0x81,0x03,0x09,0x0c,0x21,0x60, -0x49,0x46,0x0f,0x60,0x47,0x46,0x3e,0x60,0x66,0x46,0x01,0x99,0x31,0x60,0x5e,0x46, -0x02,0x99,0x31,0x60,0x51,0x46,0xcc,0x26,0x0e,0x60,0x29,0x68,0x0b,0x42,0xfc,0xd0, -0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30,0x51,0x1a,0x8e,0x42,0xdd,0xd8,0x08,0x9e, -0x72,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46,0x63,0x44,0x06,0x93,0x07,0x9a,0x73,0x68, -0x9a,0x42,0x01,0xd8,0x09,0x9b,0x73,0x60,0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93, -0xa1,0xd1,0x00,0xbe,0x33,0x68,0x72,0x68,0x9b,0x1a,0xaa,0xd5,0x9b,0xe7,0xc0,0x46, -0x10,0x10,0x00,0x40,0x18,0x10,0x00,0x40,0x0c,0x10,0x00,0x40,0x00,0x00,0xfc,0xef, -0x40,0x10,0x00,0x40,0x44,0x10,0x00,0x40,0x48,0x10,0x00,0x40,0x4c,0x10,0x00,0x40, -0x00,0x10,0x00,0x40, diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c index 695f9145a..f09f7f58a 100644 --- a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c +++ b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c @@ -2,6 +2,7 @@ /* Then postprocess output of command "arm-none-eabi-objdump -d bluenrgx.o" to make a C array of bytes */ #include +#include "../../../../src/flash/nor/bluenrg-x.h" /* Status Values ----------------------------------------------------------*/ #define SUCCESS 0 @@ -13,59 +14,22 @@ #define ERR_ERASE_REQUIRED 6 #define ERR_VERIFY_FAILED 7 -/* Flash Controller defines ---------------------------------------------------*/ -#ifdef BLUENRG_LP -#define FLASH_REG_COMMAND ((volatile uint32_t *)0x40001000) -#define FLASH_REG_CONFIG ((volatile uint32_t *)0x40001004) -#define FLASH_REG_IRQSTAT ((volatile uint32_t *)0x40001008) -#define FLASH_REG_IRQMASK ((volatile uint32_t *)0x4000100C) -#define FLASH_REG_IRQRAW ((volatile uint32_t *)0x40001010) -#define FLASH_REG_ADDRESS ((volatile uint32_t *)0x40001018) -#define FLASH_REG_UNLOCKM ((volatile uint32_t *)0x4000101C) -#define FLASH_REG_UNLOCKL ((volatile uint32_t *)0x40001020) -#define FLASH_REG_DATA0 ((volatile uint32_t *)0x40001040) -#define FLASH_REG_DATA1 ((volatile uint32_t *)0x40001044) -#define FLASH_REG_DATA2 ((volatile uint32_t *)0x40001048) -#define FLASH_REG_DATA3 ((volatile uint32_t *)0x4000104C) -#define FLASH_SIZE_REG 0x40001014 -#else -#define FLASH_REG_COMMAND ((volatile uint32_t *)0x40100000) -#define FLASH_REG_CONFIG ((volatile uint32_t *)0x40100004) -#define FLASH_REG_IRQSTAT ((volatile uint32_t *)0x40100008) -#define FLASH_REG_IRQMASK ((volatile uint32_t *)0x4010000C) -#define FLASH_REG_IRQRAW ((volatile uint32_t *)0x40100010) -#define FLASH_REG_ADDRESS ((volatile uint32_t *)0x40100018) -#define FLASH_REG_UNLOCKM ((volatile uint32_t *)0x4010001C) -#define FLASH_REG_UNLOCKL ((volatile uint32_t *)0x40100020) -#define FLASH_REG_DATA0 ((volatile uint32_t *)0x40100040) -#define FLASH_REG_DATA1 ((volatile uint32_t *)0x40100044) -#define FLASH_REG_DATA2 ((volatile uint32_t *)0x40100048) -#define FLASH_REG_DATA3 ((volatile uint32_t *)0x4010004C) -#define FLASH_SIZE_REG 0x40100014 -#endif - #define MFB_MASS_ERASE 0x01 #define MFB_PAGE_ERASE 0x02 #define DO_ERASE 0x0100 #define DO_VERIFY 0x0200 -#define FLASH_CMD_ERASE_PAGE 0x11 -#define FLASH_CMD_MASSERASE 0x22 -#define FLASH_CMD_WRITE 0x33 -#define FLASH_CMD_BURSTWRITE 0xCC -#define FLASH_INT_CMDDONE 0x01 -#define MFB_BOTTOM (0x10040000) -#define MFB_SIZE_B ((16 * (((*(uint32_t *) FLASH_SIZE_REG) + 1) >> 12)) * 1024) -#define MFB_SIZE_W (MFB_SIZE_B/4) -#define MFB_TOP (MFB_BOTTOM+MFB_SIZE_B-1) -#define MFB_PAGE_SIZE_B (2048) -#define MFB_PAGE_SIZE_W (MFB_PAGE_SIZE_B/4) + +#define MFB_BOTTOM (0x10040000) +#define MFB_SIZE_B(regs_base) ((16 * (((*(volatile uint32_t *)(regs_base + FLASH_SIZE_REG)) + 1) >> 12)) * 1024) +#define MFB_SIZE_W (MFB_SIZE_B/4) +#define MFB_TOP (MFB_BOTTOM+MFB_SIZE_B-1) +#define MFB_PAGE_SIZE_B (2048) +#define MFB_PAGE_SIZE_W (MFB_PAGE_SIZE_B/4) #define AREA_ERROR 0x01 #define AREA_MFB 0x04 -#define FLASH_WORD_LEN 4 - typedef struct { volatile uint8_t *wp; uint8_t *rp; @@ -73,29 +37,29 @@ typedef struct { /* Flash Commands --------------------------------------------------------*/ static inline __attribute__((always_inline)) uint32_t flashWrite(uint32_t address, uint8_t **data, - uint32_t writeLength) + uint32_t writeLength, uint32_t flash_regs_base) { uint32_t index, flash_word[4]; uint8_t i; - *FLASH_REG_IRQMASK = 0; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQMASK)) = 0; for (index = 0; index < writeLength; index += (FLASH_WORD_LEN*4)) { for (i = 0; i < 4; i++) flash_word[i] = (*(uint32_t *) (*data + i*4)); /* Clear the IRQ flags */ - *FLASH_REG_IRQRAW = 0x0000003F; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) = 0x0000003F; /* Load the flash address to write */ - *FLASH_REG_ADDRESS = (uint16_t)((address + index - MFB_BOTTOM) >> 2); + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_ADDRESS)) = (uint16_t)((address + index - MFB_BOTTOM) >> 2); /* Prepare and load the data to flash */ - *FLASH_REG_DATA0 = flash_word[0]; - *FLASH_REG_DATA1 = flash_word[1]; - *FLASH_REG_DATA2 = flash_word[2]; - *FLASH_REG_DATA3 = flash_word[3]; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA0)) = flash_word[0]; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA1)) = flash_word[1]; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA2)) = flash_word[2]; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA3)) = flash_word[3]; /* Flash write command */ - *FLASH_REG_COMMAND = FLASH_CMD_BURSTWRITE; + *((volatile uint32_t *)(flash_regs_base + FLASH_REG_COMMAND)) = FLASH_CMD_BURSTWRITE; /* Wait the end of the flash write command */ - while ((*FLASH_REG_IRQRAW & FLASH_INT_CMDDONE) == 0) + while ((*((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) & FLASH_INT_CMDDONE) == 0) ; *data += (FLASH_WORD_LEN * 4); } @@ -106,7 +70,8 @@ static inline __attribute__((always_inline)) uint32_t flashWrite(uint32_t addres __attribute__((naked)) __attribute__((noreturn)) void write(uint8_t *work_area_p, uint8_t *fifo_end, uint8_t *target_address, - uint32_t count) + uint32_t count, + uint32_t flash_regs_base) { uint32_t retval; volatile work_area_t *work_area = (work_area_t *) work_area_p; @@ -134,7 +99,7 @@ __attribute__((naked)) __attribute__((noreturn)) void write(uint8_t *work_area_p continue; } - retval = flashWrite((uint32_t) target_address, (uint8_t **) &work_area->rp, fifo_linear_size); + retval = flashWrite((uint32_t) target_address, (uint8_t **) &work_area->rp, fifo_linear_size, flash_regs_base); if (retval != SUCCESS) { work_area->rp = (uint8_t *)retval; break; diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc new file mode 100644 index 000000000..ff05634bb --- /dev/null +++ b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc @@ -0,0 +1,17 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0x05,0x93,0x43,0x68,0x14,0x9e,0x09,0x93,0x05,0x9b,0x05,0x00,0x07,0x91,0x06,0x92, +0x01,0x24,0xb1,0x46,0x00,0x2b,0x68,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0xfb,0xd0, +0x2b,0x68,0x00,0x2b,0x61,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0x5e,0xd9,0x6b,0x68, +0x07,0x9a,0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x4a,0x46,0x00,0x21,0x03,0x93,0xd1,0x60, +0x00,0x2b,0x42,0xd0,0x40,0x22,0x4a,0x44,0x90,0x46,0x44,0x22,0x4a,0x44,0x00,0x92, +0x48,0x22,0x4a,0x44,0x93,0x46,0x4c,0x22,0x27,0x4f,0x4a,0x44,0xbc,0x46,0x4e,0x46, +0x92,0x46,0x06,0x99,0x4b,0x46,0x61,0x44,0x08,0x00,0x00,0x99,0x18,0x36,0x6a,0x68, +0x08,0x95,0x8c,0x46,0x55,0x46,0xda,0x46,0xb3,0x46,0x10,0x33,0x04,0x92,0x11,0x68, +0x5e,0x46,0x00,0x91,0x51,0x68,0x97,0x68,0x01,0x91,0xd1,0x68,0x02,0x91,0x3f,0x21, +0x19,0x60,0x81,0x03,0x09,0x0c,0x31,0x60,0x46,0x46,0x00,0x99,0x31,0x60,0x66,0x46, +0x01,0x99,0x31,0x60,0x56,0x46,0x02,0x99,0x37,0x60,0x29,0x60,0xcc,0x26,0x49,0x46, +0x0e,0x60,0x19,0x68,0x0c,0x42,0xfc,0xd0,0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30, +0x51,0x1a,0x8e,0x42,0xdb,0xd8,0x08,0x9d,0x6a,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46, +0x63,0x44,0x06,0x93,0x07,0x9a,0x6b,0x68,0x9a,0x42,0x01,0xd8,0x09,0x9b,0x6b,0x60, +0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93,0x96,0xd1,0x00,0xbe,0x2b,0x68,0x6a,0x68, +0x9b,0x1a,0x9f,0xd5,0x90,0xe7,0xc0,0x46,0x00,0x00,0xfc,0xef, diff --git a/doc/openocd.texi b/doc/openocd.texi index 8bb4df685..8aab1ad94 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5842,15 +5842,7 @@ Note that when users ask to erase all the sectors of the flash, a mass erase com each single sector one by one. @example -flash erase_sector 0 0 79 # It will perform a mass erase on BlueNRG-1 -@end example - -@example -flash erase_sector 0 0 127 # It will perform a mass erase on BlueNRG-2 -@end example - -@example -flash erase_sector 0 0 127 # It will perform a mass erase on BlueNRG-LP +flash erase_sector 0 0 last # It will perform a mass erase @end example Triggering a mass erase is also useful when users want to disable readout protection. diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index 18b3b859b..64c4a9079 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -76,6 +76,7 @@ NOR_DRIVERS = \ NORHEADERS = \ %D%/core.h \ %D%/cc3220sf.h \ + %D%/bluenrg-x.h \ %D%/cc26xx.h \ %D%/cfi.h \ %D%/driver.h \ diff --git a/src/flash/nor/bluenrg-x.c b/src/flash/nor/bluenrg-x.c index 79821168e..f7f5e6370 100644 --- a/src/flash/nor/bluenrg-x.c +++ b/src/flash/nor/bluenrg-x.c @@ -24,119 +24,63 @@ #include #include #include "imp.h" +#include "bluenrg-x.h" -#define BLUENRG2_IDCODE (0x0200A041) -#define BLUENRGLP_IDCODE (0x0201E041) #define BLUENRG2_JTAG_REG (flash_priv_data_2.jtag_idcode_reg) #define BLUENRGLP_JTAG_REG (flash_priv_data_lp.jtag_idcode_reg) -#define FLASH_SIZE_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_size_reg) #define DIE_ID_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->die_id_reg) #define JTAG_IDCODE_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->jtag_idcode_reg) -#define FLASH_BASE(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_base) #define FLASH_PAGE_SIZE(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_page_size) -#define FLASH_REG_COMMAND(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_command) -#define FLASH_REG_IRQRAW(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_irqraw) -#define FLASH_REG_ADDRESS(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_address) -#define FLASH_REG_DATA(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_data) -#define FLASH_CMD_ERASE_PAGE 0x11 -#define FLASH_CMD_MASSERASE 0x22 -#define FLASH_CMD_WRITE 0x33 -#define FLASH_CMD_BURSTWRITE 0xCC -#define FLASH_INT_CMDDONE 0x01 -#define FLASH_WORD_LEN 4 - -/* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and - * hints how to generate the data! - */ -static const uint8_t bluenrgx_flash_write_code_2[] = { -#include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc" - }; - -static const uint8_t bluenrgx_flash_write_code_lp[] = { -#include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc" - }; struct flash_ctrl_priv_data { - uint32_t flash_size_reg; uint32_t die_id_reg; uint32_t jtag_idcode_reg; uint32_t flash_base; + uint32_t flash_regs_base; uint32_t flash_page_size; - uint32_t flash_reg_command; - uint32_t flash_reg_irqraw; - uint32_t flash_reg_address; - uint32_t flash_reg_data; uint32_t jtag_idcode; char *part_name; - const uint8_t *flash_write_code; - uint32_t flash_write_code_size; }; const struct flash_ctrl_priv_data flash_priv_data_1 = { - .flash_size_reg = 0x40100014, .die_id_reg = 0x4090001C, .jtag_idcode_reg = 0x40900028, .flash_base = 0x10040000, + .flash_regs_base = 0x40100000, .flash_page_size = 2048, - .flash_reg_command = 0x40100000, - .flash_reg_irqraw = 0x40100010, - .flash_reg_address = 0x40100018, - .flash_reg_data = 0x40100040, .jtag_idcode = 0x00000000, .part_name = "BLUENRG-1", - .flash_write_code = bluenrgx_flash_write_code_2, - .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2), }; const struct flash_ctrl_priv_data flash_priv_data_2 = { - .flash_size_reg = 0x40100014, .die_id_reg = 0x4090001C, .jtag_idcode_reg = 0x40900028, .flash_base = 0x10040000, + .flash_regs_base = 0x40100000, .flash_page_size = 2048, - .flash_reg_command = 0x40100000, - .flash_reg_irqraw = 0x40100010, - .flash_reg_address = 0x40100018, - .flash_reg_data = 0x40100040, - .jtag_idcode = BLUENRG2_IDCODE, + .jtag_idcode = 0x0200A041, .part_name = "BLUENRG-2", - .flash_write_code = bluenrgx_flash_write_code_2, - .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2), }; const struct flash_ctrl_priv_data flash_priv_data_lp = { - .flash_size_reg = 0x40001014, .die_id_reg = 0x40000000, .jtag_idcode_reg = 0x40000004, .flash_base = 0x10040000, + .flash_regs_base = 0x40001000, .flash_page_size = 2048, - .flash_reg_command = 0x40001000, - .flash_reg_irqraw = 0x40001010, - .flash_reg_address = 0x40001018, - .flash_reg_data = 0x40001040, - .jtag_idcode = BLUENRGLP_IDCODE, + .jtag_idcode = 0x0201E041, .part_name = "BLUENRG-LP", - .flash_write_code = bluenrgx_flash_write_code_lp, - .flash_write_code_size = sizeof(bluenrgx_flash_write_code_lp), }; struct bluenrgx_flash_bank { int probed; uint32_t die_id; const struct flash_ctrl_priv_data *flash_ptr; - const uint8_t *flash_write_code; - uint32_t flash_write_code_size; }; const struct flash_ctrl_priv_data *flash_ctrl[] = {&flash_priv_data_1, &flash_priv_data_2, &flash_priv_data_lp}; -static int bluenrgx_protect_check(struct flash_bank *bank) -{ - /* Nothing to do. Protection is only handled in SW. */ - return ERROR_OK; -} - /* flash_bank bluenrg-x 0 0 0 0 */ FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command) { @@ -150,6 +94,9 @@ FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command) return ERROR_FAIL; } + bank->write_start_alignment = 16; + bank->write_end_alignment = 16; + bank->driver_priv = bluenrgx_info; bluenrgx_info->probed = 0; @@ -160,6 +107,22 @@ FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command) return ERROR_OK; } +static inline uint32_t bluenrgx_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset) +{ + struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; + return bluenrgx_info->flash_ptr->flash_regs_base + reg_offset; +} + +static inline int bluenrgx_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value) +{ + return target_read_u32(bank->target, bluenrgx_get_flash_reg(bank, reg_offset), value); +} + +static inline int bluenrgx_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value) +{ + return target_write_u32(bank->target, bluenrgx_get_flash_reg(bank, reg_offset), value); +} + static int bluenrgx_erase(struct flash_bank *bank, int first, int last) { int retval = ERROR_OK; @@ -186,25 +149,25 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last) if (mass_erase) { command = FLASH_CMD_MASSERASE; address = bank->base; - if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) { + if (bluenrgx_write_flash_reg(bank, FLASH_REG_IRQRAW, 0x3f) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } - if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info), - (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) { + if (bluenrgx_write_flash_reg(bank, FLASH_REG_ADDRESS, + (address - bank->base) >> 2) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } - if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) { + if (bluenrgx_write_flash_reg(bank, FLASH_REG_COMMAND, command) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } for (int i = 0; i < 100; i++) { uint32_t value; - if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) { + if (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } @@ -222,25 +185,25 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last) address = bank->base+i*FLASH_PAGE_SIZE(bluenrgx_info); LOG_DEBUG("address = %08x, index = %d", address, i); - if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) { + if (bluenrgx_write_flash_reg(bank, FLASH_REG_IRQRAW, 0x3f) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } - if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info), - (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) { + if (bluenrgx_write_flash_reg(bank, FLASH_REG_ADDRESS, + (address - bank->base) >> 2) != ERROR_OK) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } - if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) { + if (bluenrgx_write_flash_reg(bank, FLASH_REG_COMMAND, command) != ERROR_OK) { LOG_ERROR("Failed"); return ERROR_FAIL; } for (int j = 0; j < 100; j++) { uint32_t value; - if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) { + if (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) { LOG_ERROR("Register write failed"); return ERROR_FAIL; } @@ -258,143 +221,6 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last) } -static int bluenrgx_protect(struct flash_bank *bank, int set, int first, int last) -{ - /* Protection is only handled in software: no hardware write protection - available in BlueNRG-x devices */ - int sector; - - for (sector = first; sector <= last; sector++) - bank->sectors[sector].is_protected = set; - return ERROR_OK; -} - -static int bluenrgx_write_word(struct flash_bank *bank, uint32_t address_base, uint8_t *values, uint32_t count) -{ - int retval = ERROR_OK; - struct target *target = bank->target; - struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; - - retval = target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f); - if (retval != ERROR_OK) { - LOG_ERROR("Register write failed, error code: %d", retval); - return retval; - } - - for (uint32_t i = 0; i < count; i++) { - uint32_t address = address_base + i * FLASH_WORD_LEN; - - retval = target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info), - (address - FLASH_BASE(bluenrgx_info)) >> 2); - if (retval != ERROR_OK) { - LOG_ERROR("Register write failed, error code: %d", retval); - return retval; - } - - retval = target_write_buffer(target, FLASH_REG_DATA(bluenrgx_info), - FLASH_WORD_LEN, values + i * FLASH_WORD_LEN); - if (retval != ERROR_OK) { - LOG_ERROR("Register write failed, error code: %d", retval); - return retval; - } - - retval = target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), FLASH_CMD_WRITE); - if (retval != ERROR_OK) { - LOG_ERROR("Register write failed, error code: %d", retval); - return retval; - } - - for (int j = 0; j < 100; j++) { - uint32_t reg_value; - retval = target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), ®_value); - - if (retval != ERROR_OK) { - LOG_ERROR("Register read failed, error code: %d", retval); - return retval; - } - - if (reg_value & FLASH_INT_CMDDONE) - break; - - if (j == 99) { - LOG_ERROR("Write command failed (timeout)"); - return ERROR_FAIL; - } - } - } - return retval; -} - -static int bluenrgx_write_bytes(struct flash_bank *bank, uint32_t address_base, uint8_t *buffer, uint32_t count) -{ - int retval = ERROR_OK; - struct target *target = bank->target; - uint8_t *new_buffer = NULL; - uint32_t pre_bytes = 0, post_bytes = 0, pre_word, post_word, pre_address, post_address; - - if (count == 0) { - /* Just return if there are no bytes to write */ - return retval; - } - - if (address_base & 3) { - pre_bytes = address_base & 3; - pre_address = address_base - pre_bytes; - } - - if ((count + pre_bytes) & 3) { - post_bytes = ((count + pre_bytes + 3) & ~3) - (count + pre_bytes); - post_address = (address_base + count) & ~3; - } - - if (pre_bytes || post_bytes) { - uint32_t old_count = count; - - count = old_count + pre_bytes + post_bytes; - - new_buffer = malloc(count); - - if (new_buffer == NULL) { - LOG_ERROR("odd number of bytes to write and no memory " - "for padding buffer"); - return ERROR_FAIL; - } - - LOG_INFO("Requested number of bytes to write and/or address not word aligned (%" PRIu32 "), extending to %" - PRIu32 " ", old_count, count); - - if (pre_bytes) { - if (target_read_u32(target, pre_address, &pre_word)) { - LOG_ERROR("Memory read failed"); - free(new_buffer); - return ERROR_FAIL; - } - - } - - if (post_bytes) { - if (target_read_u32(target, post_address, &post_word)) { - LOG_ERROR("Memory read failed"); - free(new_buffer); - return ERROR_FAIL; - } - - } - - memcpy(new_buffer, &pre_word, pre_bytes); - memcpy((new_buffer+((pre_bytes+old_count) & ~3)), &post_word, 4); - memcpy(new_buffer+pre_bytes, buffer, old_count); - buffer = new_buffer; - } - - retval = bluenrgx_write_word(bank, address_base - pre_bytes, buffer, count/4); - - if (new_buffer) - free(new_buffer); - - return retval; -} - static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { @@ -406,10 +232,16 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, struct working_area *source; uint32_t address = bank->base + offset; struct reg_param reg_params[5]; + struct mem_param mem_params[1]; struct armv7m_algorithm armv7m_info; int retval = ERROR_OK; - uint32_t pre_size = 0, fast_size = 0, post_size = 0; - uint32_t pre_offset = 0, fast_offset = 0, post_offset = 0; + + /* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and + * hints how to generate the data! + */ + static const uint8_t bluenrgx_flash_write_code[] = { +#include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc" + }; /* check preconditions */ if (bluenrgx_info->probed == 0) @@ -427,133 +259,105 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, return ERROR_TARGET_NOT_HALTED; } - /* We are good here and we need to compute pre_size, fast_size, post_size */ - pre_size = MIN(count, ((offset+0xF) & ~0xF) - offset); - pre_offset = offset; - fast_size = 16*((count - pre_size) / 16); - fast_offset = offset + pre_size; - post_size = (count-pre_size-fast_size) % 16; - post_offset = fast_offset + fast_size; - - LOG_DEBUG("pre_size = %08x, pre_offset=%08x", pre_size, pre_offset); - LOG_DEBUG("fast_size = %08x, fast_offset=%08x", fast_size, fast_offset); - LOG_DEBUG("post_size = %08x, post_offset=%08x", post_size, post_offset); - - /* Program initial chunk not 16 bytes aligned */ - retval = bluenrgx_write_bytes(bank, bank->base+pre_offset, (uint8_t *) buffer, pre_size); - if (retval) { - LOG_ERROR("bluenrgx_write_bytes failed %d", retval); - return ERROR_FAIL; + if (target_alloc_working_area(target, sizeof(bluenrgx_flash_write_code), + &write_algorithm) != ERROR_OK) { + LOG_WARNING("no working area available, can't do block memory writes"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } - /* Program chunk 16 bytes aligned in fast mode */ - if (fast_size) { + retval = target_write_buffer(target, write_algorithm->address, + sizeof(bluenrgx_flash_write_code), + bluenrgx_flash_write_code); + if (retval != ERROR_OK) + return retval; - if (target_alloc_working_area(target, bluenrgx_info->flash_write_code_size, - &write_algorithm) != ERROR_OK) { - LOG_WARNING("no working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + /* memory buffer */ + if (target_alloc_working_area(target, buffer_size, &source)) { + LOG_WARNING("no large enough working area available"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } - retval = target_write_buffer(target, write_algorithm->address, - bluenrgx_info->flash_write_code_size, - bluenrgx_info->flash_write_code); - if (retval != ERROR_OK) - return retval; + /* Stack pointer area */ + if (target_alloc_working_area(target, 128, + &write_algorithm_sp) != ERROR_OK) { + LOG_DEBUG("no working area for write code stack pointer"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } - /* memory buffer */ - if (target_alloc_working_area(target, buffer_size, &source)) { - LOG_WARNING("no large enough working area available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; + armv7m_info.core_mode = ARM_MODE_THREAD; - /* Stack pointer area */ - if (target_alloc_working_area(target, 64, - &write_algorithm_sp) != ERROR_OK) { - LOG_DEBUG("no working area for write code stack pointer"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); + init_reg_param(®_params[1], "r1", 32, PARAM_OUT); + init_reg_param(®_params[2], "r2", 32, PARAM_OUT); + init_reg_param(®_params[3], "r3", 32, PARAM_OUT); + init_reg_param(®_params[4], "sp", 32, PARAM_OUT); + /* Put the parameter at the first available stack location */ + init_mem_param(&mem_params[0], write_algorithm_sp->address + 80, 32, PARAM_OUT); - armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; - armv7m_info.core_mode = ARM_MODE_THREAD; + /* FIFO start address (first two words used for write and read pointers) */ + buf_set_u32(reg_params[0].value, 0, 32, source->address); + /* FIFO end address (first two words used for write and read pointers) */ + buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); + /* Flash memory address */ + buf_set_u32(reg_params[2].value, 0, 32, address); + /* Number of bytes */ + buf_set_u32(reg_params[3].value, 0, 32, count); + /* Stack pointer for program working area */ + buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_sp->address); + /* Flash register base address */ + buf_set_u32(mem_params[0].value, 0, 32, bluenrgx_info->flash_ptr->flash_regs_base); - init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); - init_reg_param(®_params[1], "r1", 32, PARAM_OUT); - init_reg_param(®_params[2], "r2", 32, PARAM_OUT); - init_reg_param(®_params[3], "r3", 32, PARAM_OUT); - init_reg_param(®_params[4], "sp", 32, PARAM_OUT); + LOG_DEBUG("source->address = " TARGET_ADDR_FMT, source->address); + LOG_DEBUG("source->address+ source->size = " TARGET_ADDR_FMT, source->address+source->size); + LOG_DEBUG("write_algorithm_sp->address = " TARGET_ADDR_FMT, write_algorithm_sp->address); + LOG_DEBUG("address = %08x", address); + LOG_DEBUG("count = %08x", count); - /* FIFO start address (first two words used for write and read pointers) */ - buf_set_u32(reg_params[0].value, 0, 32, source->address); - /* FIFO end address (first two words used for write and read pointers) */ - buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); - /* Flash memory address */ - buf_set_u32(reg_params[2].value, 0, 32, address+pre_size); - /* Number of bytes */ - buf_set_u32(reg_params[3].value, 0, 32, fast_size); - /* Stack pointer for program working area */ - buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_sp->address); + retval = target_run_flash_async_algorithm(target, + buffer, + count/16, + 16, /* Block size: we write in block of 16 bytes to enjoy burstwrite speed */ + 1, + mem_params, + 5, + reg_params, + source->address, + source->size, + write_algorithm->address, + 0, + &armv7m_info); - LOG_DEBUG("source->address = " TARGET_ADDR_FMT, source->address); - LOG_DEBUG("source->address+ source->size = " TARGET_ADDR_FMT, source->address+source->size); - LOG_DEBUG("write_algorithm_sp->address = " TARGET_ADDR_FMT, write_algorithm_sp->address); - LOG_DEBUG("address = %08x", address+pre_size); - LOG_DEBUG("count = %08x", count); + if (retval == ERROR_FLASH_OPERATION_FAILED) { + LOG_ERROR("error executing bluenrg-x flash write algorithm"); - retval = target_run_flash_async_algorithm(target, - buffer+pre_size, - fast_size/16, - 16, /* Block size: we write in block of 16 bytes to enjoy burstwrite speed */ - 0, - NULL, - 5, - reg_params, - source->address, - source->size, - write_algorithm->address, - 0, - &armv7m_info); + uint32_t error = buf_get_u32(reg_params[0].value, 0, 32); - if (retval == ERROR_FLASH_OPERATION_FAILED) { - LOG_ERROR("error executing bluenrg-x flash write algorithm"); - - uint32_t error = buf_get_u32(reg_params[0].value, 0, 32); - - if (error != 0) - LOG_ERROR("flash write failed = %08" PRIx32, error); - } + if (error != 0) + LOG_ERROR("flash write failed = %08" PRIx32, error); + } + if (retval == ERROR_OK) { + uint32_t rp; + /* Read back rp and check that is valid */ + retval = target_read_u32(target, source->address+4, &rp); if (retval == ERROR_OK) { - uint32_t rp; - /* Read back rp and check that is valid */ - retval = target_read_u32(target, source->address+4, &rp); - if (retval == ERROR_OK) { - if ((rp < source->address+8) || (rp > (source->address + source->size))) { - LOG_ERROR("flash write failed = %08" PRIx32, rp); - retval = ERROR_FLASH_OPERATION_FAILED; - } + if ((rp < source->address+8) || (rp > (source->address + source->size))) { + LOG_ERROR("flash write failed = %08" PRIx32, rp); + retval = ERROR_FLASH_OPERATION_FAILED; } } - target_free_working_area(target, source); - target_free_working_area(target, write_algorithm); - target_free_working_area(target, write_algorithm_sp); - - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - destroy_reg_param(®_params[3]); - destroy_reg_param(®_params[4]); - if (retval != ERROR_OK) - return retval; - } + target_free_working_area(target, source); + target_free_working_area(target, write_algorithm); + target_free_working_area(target, write_algorithm_sp); + + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_params[2]); + destroy_reg_param(®_params[3]); + destroy_reg_param(®_params[4]); + destroy_mem_param(&mem_params[0]); - /* Program chunk at end, not addressable by fast burst write algorithm */ - retval = bluenrgx_write_bytes(bank, bank->base+post_offset, - (uint8_t *) (buffer+pre_size+fast_size), post_size); - if (retval) { - LOG_ERROR("bluenrgx_write_bytes failed %d", retval); - return ERROR_FAIL; - } return retval; } @@ -567,7 +371,7 @@ static int bluenrgx_probe(struct flash_bank *bank) if (retval != ERROR_OK) return retval; - if (idcode != BLUENRGLP_IDCODE) { + if (idcode != flash_priv_data_lp.jtag_idcode) { retval = target_read_u32(bank->target, BLUENRG2_JTAG_REG, &idcode); if (retval != ERROR_OK) return retval; @@ -575,19 +379,16 @@ static int bluenrgx_probe(struct flash_bank *bank) /* Default device is BlueNRG-1 */ bluenrgx_info->flash_ptr = &flash_priv_data_1; - bluenrgx_info->flash_write_code = flash_priv_data_1.flash_write_code; - bluenrgx_info->flash_write_code_size = flash_priv_data_1.flash_write_code_size; + bank->base = flash_priv_data_1.flash_base; for (i = 0; i < (int)(sizeof(flash_ctrl)/sizeof(*flash_ctrl)); i++) { if (idcode == (*flash_ctrl[i]).jtag_idcode) { bluenrgx_info->flash_ptr = flash_ctrl[i]; - bluenrgx_info->flash_write_code = (*flash_ctrl[i]).flash_write_code; - bluenrgx_info->flash_write_code_size = (*flash_ctrl[i]).flash_write_code_size; + bank->base = (*flash_ctrl[i]).flash_base; break; } } - - retval = target_read_u32(bank->target, FLASH_SIZE_REG(bluenrgx_info), &size_info); + retval = bluenrgx_read_flash_reg(bank, FLASH_SIZE_REG, &size_info); if (retval != ERROR_OK) return retval; @@ -596,7 +397,6 @@ static int bluenrgx_probe(struct flash_bank *bank) return retval; bank->size = (size_info + 1) * FLASH_WORD_LEN; - bank->base = FLASH_BASE(bluenrgx_info); bank->num_sectors = bank->size/FLASH_PAGE_SIZE(bluenrgx_info); bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector) * bank->num_sectors); @@ -650,12 +450,12 @@ const struct flash_driver bluenrgx_flash = { .name = "bluenrg-x", .flash_bank_command = bluenrgx_flash_bank_command, .erase = bluenrgx_erase, - .protect = bluenrgx_protect, + .protect = NULL, .write = bluenrgx_write, .read = default_flash_read, .probe = bluenrgx_probe, .erase_check = default_flash_blank_check, - .protect_check = bluenrgx_protect_check, + .protect_check = NULL, .auto_probe = bluenrgx_auto_probe, .info = bluenrgx_get_info, }; diff --git a/src/flash/nor/bluenrg-x.h b/src/flash/nor/bluenrg-x.h new file mode 100644 index 000000000..3b84b8b19 --- /dev/null +++ b/src/flash/nor/bluenrg-x.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2019 by STMicroelectronics. * + * * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef OPENOCD_FLASH_NOR_BLUENRGX_H +#define OPENOCD_FLASH_NOR_BLUENRGX_H + +/* Flash Controller registers offsets */ +#define FLASH_REG_COMMAND 0x00 +#define FLASH_REG_CONFIG 0x04 +#define FLASH_REG_IRQSTAT 0x08 +#define FLASH_REG_IRQMASK 0x0C +#define FLASH_REG_IRQRAW 0x10 +#define FLASH_REG_ADDRESS 0x18 +#define FLASH_REG_UNLOCKM 0x1C +#define FLASH_REG_UNLOCKL 0x20 +#define FLASH_REG_DATA0 0x40 +#define FLASH_REG_DATA1 0x44 +#define FLASH_REG_DATA2 0x48 +#define FLASH_REG_DATA3 0x4C +#define FLASH_SIZE_REG 0x14 + +/* Flash Controller commands */ +#define FLASH_CMD_ERASE_PAGE 0x11 +#define FLASH_CMD_MASSERASE 0x22 +#define FLASH_CMD_WRITE 0x33 +#define FLASH_CMD_BURSTWRITE 0xCC +#define FLASH_INT_CMDDONE 0x01 + +#define FLASH_WORD_LEN 4 + +#endif /* OPENOCD_FLASH_NOR_BLUENRGX_H */ diff --git a/tcl/target/bluenrg-x.cfg b/tcl/target/bluenrg-x.cfg index 691bbbf83..a9d321ee6 100644 --- a/tcl/target/bluenrg-x.cfg +++ b/tcl/target/bluenrg-x.cfg @@ -23,13 +23,7 @@ if { [info exists WORKAREASIZE] } { adapter speed 4000 -if { [info exists CPUTAPID] } { - set _CPUTAPID $CPUTAPID -} else { - set _CPUTAPID 0x0bb11477 -} - -swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID +swj_newdap $_CHIPNAME cpu -expected-id 0x0bb11477 -expected-id 0x0bc11477 dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu set _TARGETNAME $_CHIPNAME.cpu From 82a5c55dc357b042b6755b343c920baebd410874 Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Fri, 28 Feb 2020 16:56:11 -0600 Subject: [PATCH 177/354] flash/nor: update support for TI MSP432 devices Added fixes for issues found in additional code reviews. Fixed host Endianness issues with using buffer reads and writes instead of the *_u32 variants. Changed code that tried to ID banks by hardcode bank_number values to use instead the bank base address. This fixes problems using configurations with multiple devices. Note that this replaces Change 4786 which has been abandoned because of extensive changes to the code to stop IDing banks by name. And I think I really messed up a rebase/merge on the document file. Tested on MSP432P401R, MSP432P4111, and MSP432E401Y Launchpads. Change-Id: Id05798b3aa78ae5cbe725ee762a164d673ee5767 Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5481 Tested-by: jenkins Reviewed-by: Tomas Vanek --- doc/openocd.texi | 8 +- src/flash/nor/msp432.c | 229 +++++++++++++++++++++-------------------- src/flash/nor/msp432.h | 7 +- 3 files changed, 127 insertions(+), 117 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 8aab1ad94..454ae0675 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6299,14 +6299,14 @@ if @{ [info exists IMEMORY] && [string equal $IMEMORY true] @} @{ All versions of the SimpleLink MSP432 microcontrollers from Texas Instruments include internal flash. The msp432 flash driver automatically recognizes the specific version's flash parameters and autoconfigures itself. -Main program flash (starting at address 0) is flash bank 0. Information flash -region on MSP432P4 versions (starting at address 0x200000) is flash bank 1. +Main program flash starts at address 0. The information flash region on +MSP432P4 versions starts at address 0x200000. @example flash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME @end example -@deffn Command {msp432 mass_erase} [main|all] +@deffn Command {msp432 mass_erase} bank_id [main|all] Performs a complete erase of flash. By default, @command{mass_erase} will erase only the main program flash. @@ -6315,7 +6315,7 @@ main program and information flash regions. To also erase the BSL in information flash, the user must first use the @command{bsl} command. @end deffn -@deffn Command {msp432 bsl} [unlock|lock] +@deffn Command {msp432 bsl} bank_id [unlock|lock] On MSP432P4 versions, @command{bsl} unlocks and locks the bootstrap loader (BSL) region in information flash so that flash commands can erase or write the BSL. Leave the BSL locked to prevent accidentally corrupting the bootstrap loader. diff --git a/src/flash/nor/msp432.c b/src/flash/nor/msp432.c index e9e4be33a..95c99b970 100644 --- a/src/flash/nor/msp432.c +++ b/src/flash/nor/msp432.c @@ -49,7 +49,8 @@ struct msp432_bank { int family_type; int device_type; uint32_t sector_length; - bool probed[2]; + bool probed_main; + bool probed_info; bool unlock_bsl; struct working_area *working_area; struct armv7m_algorithm armv7m_info; @@ -194,8 +195,7 @@ static int msp432_exec_cmd(struct target *target, struct msp432_algo_params return retval; /* Write out command to target memory */ - retval = target_write_buffer(target, ALGO_FLASH_COMMAND_ADDR, - sizeof(command), (uint8_t *)&command); + retval = target_write_u32(target, ALGO_FLASH_COMMAND_ADDR, command); return retval; } @@ -210,8 +210,7 @@ static int msp432_wait_return_code(struct target *target) start_ms = timeval_ms(); while ((0 == return_code) || (FLASH_BUSY == return_code)) { - retval = target_read_buffer(target, ALGO_RETURN_CODE_ADDR, - sizeof(return_code), (uint8_t *)&return_code); + retval = target_read_u32(target, ALGO_RETURN_CODE_ADDR, &return_code); if (ERROR_OK != retval) return retval; @@ -253,8 +252,7 @@ static int msp432_wait_inactive(struct target *target, uint32_t buffer) start_ms = timeval_ms(); while (BUFFER_INACTIVE != status_code) { - retval = target_read_buffer(target, status_addr, sizeof(status_code), - (uint8_t *)&status_code); + retval = target_read_u32(target, status_addr, &status_code); if (ERROR_OK != retval) return retval; @@ -477,15 +475,23 @@ COMMAND_HANDLER(msp432_mass_erase_command) struct flash_bank *bank; struct msp432_bank *msp432_bank; bool all; + int retval; - if (0 == CMD_ARGC) { + if (1 > CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + + retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (retval != ERROR_OK) + return retval; + + if (1 == CMD_ARGC) { all = false; - } else if (1 == CMD_ARGC) { + } else if (2 == CMD_ARGC) { /* Check argument for how much to erase */ - if (0 == strcmp(CMD_ARGV[0], "main")) + if (0 == strcmp(CMD_ARGV[1], "main")) all = false; - else if (0 == strcmp(CMD_ARGV[0], "all")) + else if (0 == strcmp(CMD_ARGV[1], "all")) all = true; else return ERROR_COMMAND_SYNTAX_ERROR; @@ -493,10 +499,6 @@ COMMAND_HANDLER(msp432_mass_erase_command) return ERROR_COMMAND_SYNTAX_ERROR; } - retval = get_flash_bank_by_num(0, &bank); - if (ERROR_OK != retval) - return retval; - msp432_bank = bank->driver_priv; if (MSP432E4 == msp432_bank->family_type) { @@ -513,7 +515,7 @@ COMMAND_HANDLER(msp432_mass_erase_command) LOG_INFO("msp432: Mass erase of flash is complete"); } else { LOG_INFO("msp432: Mass erase of %s is complete", - all ? "main + info flash" : "main flash"); + all ? "main + information flash" : "main flash"); } return ERROR_OK; @@ -523,13 +525,14 @@ COMMAND_HANDLER(msp432_bsl_command) { struct flash_bank *bank; struct msp432_bank *msp432_bank; + int retval; - if (1 < CMD_ARGC) + if (1 > CMD_ARGC) return ERROR_COMMAND_SYNTAX_ERROR; - retval = get_flash_bank_by_num(0, &bank); - if (ERROR_OK != retval) + retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (retval != ERROR_OK) return retval; msp432_bank = bank->driver_priv; @@ -539,13 +542,16 @@ COMMAND_HANDLER(msp432_bsl_command) return ERROR_OK; } - if (1 == CMD_ARGC) { - if (0 == strcmp(CMD_ARGV[0], "lock")) + if (2 == CMD_ARGC) { + if (0 == strcmp(CMD_ARGV[1], "lock")) msp432_bank->unlock_bsl = false; - else if (0 == strcmp(CMD_ARGV[0], "unlock")) + else if (0 == strcmp(CMD_ARGV[1], "unlock")) msp432_bank->unlock_bsl = true; else return ERROR_COMMAND_SYNTAX_ERROR; + } else if (1 != CMD_ARGC) { + /* Extra, unknown argument passed in */ + return ERROR_COMMAND_SYNTAX_ERROR; } LOG_INFO("msp432: BSL flash region is currently %slocked", @@ -561,6 +567,7 @@ FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command) if (CMD_ARGC < 6) return ERROR_COMMAND_SYNTAX_ERROR; + /* Create shared private struct for flash banks */ msp432_bank = malloc(sizeof(struct msp432_bank)); if (NULL == msp432_bank) return ERROR_FAIL; @@ -571,14 +578,14 @@ FLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command) msp432_bank->family_type = MSP432_NO_FAMILY; msp432_bank->device_type = MSP432_NO_TYPE; msp432_bank->sector_length = 0x1000; - msp432_bank->probed[0] = false; - msp432_bank->probed[1] = false; + msp432_bank->probed_main = false; + msp432_bank->probed_info = false; msp432_bank->unlock_bsl = false; msp432_bank->working_area = NULL; - /* Finish initialization of bank 0 (main flash) */ + /* Finish up initial settings here */ bank->driver_priv = msp432_bank; - bank->next = NULL; + bank->base = FLASH_BASE; return ERROR_OK; } @@ -589,6 +596,9 @@ static int msp432_erase(struct flash_bank *bank, int first, int last) struct msp432_bank *msp432_bank = bank->driver_priv; struct msp432_algo_params algo_params; + bool is_main = FLASH_BASE == bank->base; + bool is_info = P4_FLASH_INFO_BASE == bank->base; + int retval; if (TARGET_HALTED != target->state) { @@ -597,8 +607,7 @@ static int msp432_erase(struct flash_bank *bank, int first, int last) } /* Do a mass erase if user requested all sectors of main flash */ - if ((0 == bank->bank_number) && (first == 0) && - (last == (bank->num_sectors - 1))) { + if (is_main && (first == 0) && (last == (bank->num_sectors - 1))) { /* Request mass erase of main flash */ return msp432_mass_erase(bank, false); } @@ -611,7 +620,7 @@ static int msp432_erase(struct flash_bank *bank, int first, int last) msp432_init_params(&algo_params); /* Adjust params if this is the info bank */ - if (1 == bank->bank_number) { + if (is_info) { buf_set_u32(algo_params.erase_param, 0, 32, FLASH_ERASE_INFO); /* And flag if BSL is unlocked */ if (msp432_bank->unlock_bsl) @@ -622,11 +631,11 @@ static int msp432_erase(struct flash_bank *bank, int first, int last) for (int i = first; i <= last; i++) { /* Skip TVL (read-only) sector of the info bank */ - if (1 == bank->bank_number && 1 == i) + if (is_info && 1 == i) continue; /* Skip BSL sectors of info bank if locked */ - if (1 == bank->bank_number && (2 == i || 3 == i) && + if (is_info && (2 == i || 3 == i) && !msp432_bank->unlock_bsl) continue; @@ -666,6 +675,8 @@ static int msp432_write(struct flash_bank *bank, const uint8_t *buffer, long long start_ms; long long elapsed_ms; + bool is_info = P4_FLASH_INFO_BASE == bank->base; + int retval; if (TARGET_HALTED != target->state) { @@ -679,7 +690,7 @@ static int msp432_write(struct flash_bank *bank, const uint8_t *buffer, * The BSL region in sectors 2 and 3 of the info flash may be unlocked * The helper algorithm will hang on attempts to write to TVL */ - if (1 == bank->bank_number) { + if (is_info) { /* Set read-only start to TVL sector */ uint32_t start = 0x1000; /* Set read-only end after BSL region if locked */ @@ -722,7 +733,7 @@ static int msp432_write(struct flash_bank *bank, const uint8_t *buffer, buf_set_u32(algo_params.length, 0, 32, count); /* Check if this is the info bank */ - if (1 == bank->bank_number) { + if (is_info) { /* And flag if BSL is unlocked */ if (msp432_bank->unlock_bsl) buf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL); @@ -753,8 +764,8 @@ static int msp432_write(struct flash_bank *bank, const uint8_t *buffer, } /* Signal the flash helper algorithm that data is ready to flash */ - retval = target_write_buffer(target, ALGO_BUFFER1_STATUS_ADDR, - sizeof(data_ready), (uint8_t *)&data_ready); + retval = target_write_u32(target, ALGO_BUFFER1_STATUS_ADDR, + data_ready); if (ERROR_OK != retval) { (void)msp432_quit(bank); return ERROR_FLASH_OPERATION_FAILED; @@ -793,20 +804,23 @@ static int msp432_probe(struct flash_bank *bank) struct target *target = bank->target; struct msp432_bank *msp432_bank = bank->driver_priv; - char *name; - uint32_t device_id; uint32_t hardware_rev; - uint32_t base; uint32_t sector_length; uint32_t size; int num_sectors; - int bank_id; + + bool is_main = FLASH_BASE == bank->base; + bool is_info = P4_FLASH_INFO_BASE == bank->base; int retval; - bank_id = bank->bank_number; + /* Check if this bank has already been successfully probed */ + if (is_main && msp432_bank->probed_main) + return ERROR_OK; + if (is_info && msp432_bank->probed_info) + return ERROR_OK; /* Read the flash size register to determine this is a P4 or not */ /* MSP432P4s will return the size of flash. MSP432E4s will return zero */ @@ -849,63 +863,16 @@ static int msp432_probe(struct flash_bank *bank) msp432_bank->device_type = msp432_device_type(msp432_bank->family_type, msp432_bank->device_id, msp432_bank->hardware_rev); - /* If not already allocated, create the info bank for MSP432P4 */ - /* We could not determine it was needed until device was probed */ - if (MSP432P4 == msp432_bank->family_type) { - /* If we've been given bank 1, then this was already done */ - if (0 == bank_id) { - /* And only allocate it if it doesn't exist yet */ - if (NULL == bank->next) { - struct flash_bank *info_bank; - info_bank = malloc(sizeof(struct flash_bank)); - if (NULL == info_bank) - return ERROR_FAIL; - - name = malloc(strlen(bank->name)+1); - if (NULL == name) { - free(info_bank); - return ERROR_FAIL; - } - strcpy(name, bank->name); - - /* Initialize bank 1 (info region) */ - info_bank->name = name; - info_bank->target = bank->target; - info_bank->driver = bank->driver; - info_bank->driver_priv = bank->driver_priv; - info_bank->bank_number = 1; - info_bank->base = 0x00200000; - info_bank->size = 0; - info_bank->chip_width = 0; - info_bank->bus_width = 0; - info_bank->erased_value = 0xff; - info_bank->default_padded_value = 0xff; - info_bank->write_start_alignment = 0; - info_bank->write_end_alignment = 0; - info_bank->minimal_write_gap = FLASH_WRITE_GAP_SECTOR; - info_bank->num_sectors = 0; - info_bank->sectors = NULL; - info_bank->num_prot_blocks = 0; - info_bank->prot_blocks = NULL; - info_bank->next = NULL; - - /* Enable the new bank */ - bank->next = info_bank; - } - } - } - if (MSP432P4 == msp432_bank->family_type) { /* Set up MSP432P4 specific flash parameters */ - if (0 == bank_id) { + if (is_main) { retval = target_read_u32(target, P4_FLASH_MAIN_SIZE_REG, &size); if (ERROR_OK != retval) return retval; - base = P4_FLASH_MAIN_BASE; sector_length = P4_SECTOR_LENGTH; num_sectors = size / sector_length; - } else if (1 == bank_id) { + } else if (is_info) { if (msp432_bank->device_type == MSP432P411X || msp432_bank->device_type == MSP432P411X_GUESS) { /* MSP432P411x has an info size register, use that for size */ @@ -916,19 +883,22 @@ static int msp432_probe(struct flash_bank *bank) /* All other MSP432P401x devices have fixed info region size */ size = 0x4000; /* 16 KB info region */ } - base = P4_FLASH_INFO_BASE; sector_length = P4_SECTOR_LENGTH; num_sectors = size / sector_length; } else { - /* Invalid bank number somehow */ + /* Invalid bank somehow */ return ERROR_FAIL; } } else { /* Set up MSP432E4 specific flash parameters */ - base = E4_FLASH_BASE; - size = E4_FLASH_SIZE; - sector_length = E4_SECTOR_LENGTH; - num_sectors = size / sector_length; + if (is_main) { + size = E4_FLASH_SIZE; + sector_length = E4_SECTOR_LENGTH; + num_sectors = size / sector_length; + } else { + /* Invalid bank somehow */ + return ERROR_FAIL; + } } if (NULL != bank->sectors) { @@ -936,11 +906,12 @@ static int msp432_probe(struct flash_bank *bank) bank->sectors = NULL; } - bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); - if (NULL == bank->sectors) - return ERROR_FAIL; + if (num_sectors > 0) { + bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); + if (NULL == bank->sectors) + return ERROR_FAIL; + } - bank->base = base; bank->size = size; bank->write_start_alignment = 0; bank->write_end_alignment = 0; @@ -955,7 +926,31 @@ static int msp432_probe(struct flash_bank *bank) } /* We've successfully determined the stats on this flash bank */ - msp432_bank->probed[bank_id] = true; + if (is_main) + msp432_bank->probed_main = true; + if (is_info) + msp432_bank->probed_info = true; + + if (is_main && MSP432P4 == msp432_bank->family_type) { + /* Create the info flash bank needed by MSP432P4 variants */ + struct flash_bank *info = calloc(sizeof(struct flash_bank), 1); + if (NULL == info) + return ERROR_FAIL; + + /* Create a name for the info bank, append "_1" to main name */ + char *name = malloc(strlen(bank->name) + 3); + strcpy(name, bank->name); + strcat(name, "_1"); + + /* Initialize info bank */ + info->name = name; + info->target = bank->target; + info->driver = bank->driver; + info->driver_priv = msp432_bank; + info->base = P4_FLASH_INFO_BASE; + + flash_bank_add(info); + } /* If we fall through to here, then all went well */ @@ -966,15 +961,17 @@ static int msp432_auto_probe(struct flash_bank *bank) { struct msp432_bank *msp432_bank = bank->driver_priv; + bool is_main = FLASH_BASE == bank->base; + bool is_info = P4_FLASH_INFO_BASE == bank->base; + int retval = ERROR_OK; - if (bank->bank_number < 0 || bank->bank_number > 1) { - /* Invalid bank number somehow */ - return ERROR_FAIL; - } - - if (!msp432_bank->probed[bank->bank_number]) - retval = msp432_probe(bank); + if (is_main) + if (!msp432_bank->probed_main) + retval = msp432_probe(bank); + if (is_info) + if (!msp432_bank->probed_info) + retval = msp432_probe(bank); return retval; } @@ -1036,12 +1033,21 @@ static int msp432_info(struct flash_bank *bank, char *buf, int buf_size) return ERROR_OK; } +static int msp432_protect_check(struct flash_bank *bank) +{ + /* Added to suppress warning, not needed for MSP432 flash */ + return ERROR_OK; +} + static void msp432_flash_free_driver_priv(struct flash_bank *bank) { + bool is_main = FLASH_BASE == bank->base; + /* A single private struct is shared between main and info banks */ - /* Only free it on the call for main bank (#0) */ - if ((0 == bank->bank_number) && (NULL != bank->driver_priv)) + /* Only free it on the call for main bank */ + if (is_main && (NULL != bank->driver_priv)) free(bank->driver_priv); + /* Forget about the private struct on both main and info banks */ bank->driver_priv = NULL; } @@ -1052,14 +1058,14 @@ static const struct command_registration msp432_exec_command_handlers[] = { .handler = msp432_mass_erase_command, .mode = COMMAND_EXEC, .help = "Erase entire flash memory on device.", - .usage = "['main' | 'all']", + .usage = "bank_id ['main' | 'all']", }, { .name = "bsl", .handler = msp432_bsl_command, .mode = COMMAND_EXEC, .help = "Allow BSL to be erased or written by flash commands.", - .usage = "['unlock' | 'lock']", + .usage = "bank_id ['unlock' | 'lock']", }, COMMAND_REGISTRATION_DONE }; @@ -1085,6 +1091,7 @@ const struct flash_driver msp432_flash = { .probe = msp432_probe, .auto_probe = msp432_auto_probe, .erase_check = default_flash_blank_check, + .protect_check = msp432_protect_check, .info = msp432_info, .free_driver_priv = msp432_flash_free_driver_priv, }; diff --git a/src/flash/nor/msp432.h b/src/flash/nor/msp432.h index ffefa8f43..663393b79 100644 --- a/src/flash/nor/msp432.h +++ b/src/flash/nor/msp432.h @@ -34,14 +34,17 @@ #define MSP432E411Y 7 /* MSP432E401Y device */ #define MSP432E4X_GUESS 8 /* Assuming it's an MSP432E4x device */ +/* Common MSP432 flash parameters */ +#define FLASH_BASE 0x00000000 + /* MSP432P4 flash parameters */ -#define P4_FLASH_MAIN_BASE 0x00000000 +#define P4_FLASH_MAIN_BASE FLASH_BASE #define P4_FLASH_INFO_BASE 0x00200000 #define P4_SECTOR_LENGTH 0x1000 #define P4_ALGO_ENTRY_ADDR 0x01000110 /* MSP432E4 flash paramters */ -#define E4_FLASH_BASE 0x00000000 +#define E4_FLASH_BASE FLASH_BASE #define E4_FLASH_SIZE 0x100000 #define E4_SECTOR_LENGTH 0x4000 #define E4_ALGO_ENTRY_ADDR 0x20000110 From b304971f380d89d5e934859b2c36e81c26df6eee Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 15 Jan 2020 05:42:03 +0100 Subject: [PATCH 178/354] tcl/target: Unify Renesas R-Car JTAG reset config Both Gen2 and Gen3 used the same init_reset{} implementation, pull it into common file and include it from both generations. Moreover, this behavior is SoC specific, not board specific, so move the common init_reset into target/ directory. Change-Id: I5489a4bff9a786da8cb7fd7a515b0c9ce9dc16e3 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5400 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/board/renesas_salvator-xs.cfg | 14 -------------- tcl/target/renesas_rcar_gen2.cfg | 2 ++ tcl/target/renesas_rcar_gen3.cfg | 2 ++ .../renesas_rcar_reset_common.cfg} | 0 4 files changed, 4 insertions(+), 14 deletions(-) rename tcl/{board/renesas_gen2_common.cfg => target/renesas_rcar_reset_common.cfg} (100%) diff --git a/tcl/board/renesas_salvator-xs.cfg b/tcl/board/renesas_salvator-xs.cfg index e6f4da337..6d3096ec1 100644 --- a/tcl/board/renesas_salvator-xs.cfg +++ b/tcl/board/renesas_salvator-xs.cfg @@ -7,17 +7,3 @@ if { ![info exists SOC] } { set SOC H3 } source [find target/renesas_rcar_gen3.cfg] - -reset_config trst_and_srst srst_nogate - -proc init_reset {mode} { - # Assert both resets: equivalent to a power-on reset - adapter assert trst assert srst - - # Deassert TRST to begin TAP communication - adapter deassert trst assert srst - - # TAP should now be responsive, validate the scan-chain - jtag arp_init -} - diff --git a/tcl/target/renesas_rcar_gen2.cfg b/tcl/target/renesas_rcar_gen2.cfg index 9f7421d91..91baa6c90 100644 --- a/tcl/target/renesas_rcar_gen2.cfg +++ b/tcl/target/renesas_rcar_gen2.cfg @@ -120,4 +120,6 @@ if { [string equal $_boot_core CA15] } { setup_ca a7 $CA7_DBGBASE $_num_ca7 0 } +source [find target/renesas_rcar_reset_common.cfg] + eval "target smp $smp_targets" diff --git a/tcl/target/renesas_rcar_gen3.cfg b/tcl/target/renesas_rcar_gen3.cfg index 34c191827..72f185d61 100644 --- a/tcl/target/renesas_rcar_gen3.cfg +++ b/tcl/target/renesas_rcar_gen3.cfg @@ -166,4 +166,6 @@ if { [string equal $_boot_core CA57] } { setup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0 } +source [find target/renesas_rcar_reset_common.cfg] + eval "target smp $smp_targets" diff --git a/tcl/board/renesas_gen2_common.cfg b/tcl/target/renesas_rcar_reset_common.cfg similarity index 100% rename from tcl/board/renesas_gen2_common.cfg rename to tcl/target/renesas_rcar_reset_common.cfg From 123e10288df62e6f66426cdab7adb93fd7348d5f Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Fri, 7 Feb 2020 12:52:14 +0100 Subject: [PATCH 179/354] flash/stm32h7x: fix bank sizes for devices with trimmed flash STM32H7yxxI: dual independent 1 MByte banks STM32H7yxxG: dual independent 512 Kbyte banks STM32H7yxxB: single 128 Kbyte bank where y = [4/5] or [A/B] references: (documents are available in www.st.com) - STM32H7[4/5]x[G/I] : DS12110 Rev 7 >> 3.3.1 Embedded Flash memory - STM32H750xB : RM0433 Rev 6 >> Table 11. Flash memory organization on STM32H750xB devices - STM32H7[A/B]x[B/G/I] : RM0455 Rev 3 >> 4.3.4 Flash memory architecture and usage Change-Id: Ic9346964ef2554abf47f5832e25adfdc77bd323e Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5442 Tested-by: jenkins Reviewed-by: Christopher Head --- src/flash/nor/stm32h7x.c | 77 +++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 7882c11a7..6edbc00fa 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -117,7 +117,7 @@ struct stm32h7x_part_info { unsigned int block_size; /* flash write word size in bytes */ uint16_t max_flash_size_kb; uint8_t has_dual_bank; - uint16_t first_bank_size_kb; /* Used when has_dual_bank is true */ + uint16_t max_bank_size_kb; /* Used when has_dual_bank is true */ uint32_t flash_regs_base; /* Flash controller registers location */ uint32_t fsize_addr; /* Location of FSIZE register */ uint32_t wps_group_size; /* write protection group sectors' count */ @@ -173,7 +173,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .page_size_kb = 128, .block_size = 32, .max_flash_size_kb = 2048, - .first_bank_size_kb = 1024, + .max_bank_size_kb = 1024, .has_dual_bank = 1, .flash_regs_base = FLASH_REG_BASE_B0, .fsize_addr = 0x1FF1E880, @@ -189,7 +189,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .page_size_kb = 8, .block_size = 16, .max_flash_size_kb = 2048, - .first_bank_size_kb = 1024, + .max_bank_size_kb = 1024, .has_dual_bank = 1, .flash_regs_base = FLASH_REG_BASE_B0, .fsize_addr = 0x08FFF80C, @@ -740,8 +740,6 @@ static int stm32x_probe(struct flash_bank *bank) struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; uint16_t flash_size_in_kb; uint32_t device_id; - uint32_t base_address = FLASH_BANK0_ADDRESS; - uint32_t second_bank_base; stm32x_info->probed = false; stm32x_info->part_info = NULL; @@ -776,33 +774,58 @@ static int stm32x_probe(struct flash_bank *bank) } else LOG_INFO("flash size probed value %d", flash_size_in_kb); - /* Lower flash size devices are single bank */ - if (stm32x_info->part_info->has_dual_bank && (flash_size_in_kb > stm32x_info->part_info->first_bank_size_kb)) { - /* Use the configured base address to determine if this is the first or second flash bank. - * Verify that the base address is reasonably correct and determine the flash bank size + + + + /* setup bank size */ + const uint32_t bank1_base = FLASH_BANK0_ADDRESS; + const uint32_t bank2_base = bank1_base + stm32x_info->part_info->max_bank_size_kb * 1024; + bool has_dual_bank = stm32x_info->part_info->has_dual_bank; + + switch (device_id) { + case 0x450: + case 0x480: + /* For STM32H74x/75x and STM32H7Ax/Bx + * - STM32H7xxxI devices contains dual bank, 1 Mbyte each + * - STM32H7xxxG devices contains dual bank, 512 Kbyte each + * - STM32H7xxxB devices contains single bank, 128 Kbyte + * - the second bank starts always from 0x08100000 */ - second_bank_base = base_address + stm32x_info->part_info->first_bank_size_kb * 1024; - if (bank->base == second_bank_base) { - /* This is the second bank */ - base_address = second_bank_base; - flash_size_in_kb = flash_size_in_kb - stm32x_info->part_info->first_bank_size_kb; - /* bank1 also uses a register offset */ - stm32x_info->flash_regs_base = FLASH_REG_BASE_B1; - } else if (bank->base == base_address) { - /* This is the first bank */ - flash_size_in_kb = stm32x_info->part_info->first_bank_size_kb; - } else { - LOG_WARNING("STM32H flash bank base address config is incorrect. " - TARGET_ADDR_FMT " but should rather be 0x%" PRIx32 " or 0x%" PRIx32, - bank->base, base_address, second_bank_base); + if (flash_size_in_kb == 128) + has_dual_bank = false; + else + /* flash size is 2M or 1M */ + flash_size_in_kb /= 2; + break; + default: + LOG_ERROR("unsupported device"); + return ERROR_FAIL; + } + + if (has_dual_bank) { + LOG_INFO("STM32H7 flash has dual banks"); + if (bank->base != bank1_base && bank->base != bank2_base) { + LOG_ERROR("STM32H7 flash bank base address config is incorrect. " + TARGET_ADDR_FMT " but should rather be 0x%" PRIx32 " or 0x%" PRIx32, + bank->base, bank1_base, bank2_base); return ERROR_FAIL; } - LOG_INFO("STM32H flash has dual banks. Bank (%d) size is %dkb, base address is 0x%" PRIx32, - bank->bank_number, flash_size_in_kb, base_address); } else { - LOG_INFO("STM32H flash size is %dkb, base address is 0x%" PRIx32, flash_size_in_kb, base_address); + LOG_INFO("STM32H7 flash has a single bank"); + if (bank->base == bank2_base) { + LOG_ERROR("this device has a single bank only"); + return ERROR_FAIL; + } else if (bank->base != bank1_base) { + LOG_ERROR("STM32H7 flash bank base address config is incorrect. " + TARGET_ADDR_FMT " but should be 0x%" PRIx32, + bank->base, bank1_base); + return ERROR_FAIL; + } } + LOG_INFO("Bank (%d) size is %d kb, base address is 0x%" PRIx32, + bank->bank_number, flash_size_in_kb, (uint32_t) bank->base); + /* if the user sets the size manually then ignore the probed value * this allows us to work around devices that have an invalid flash size register value */ if (stm32x_info->user_bank_size) { @@ -815,8 +838,6 @@ static int stm32x_probe(struct flash_bank *bank) /* did we assign flash size? */ assert(flash_size_in_kb != 0xffff); - - bank->base = base_address; bank->size = flash_size_in_kb * 1024; bank->write_start_alignment = stm32x_info->part_info->block_size; bank->write_end_alignment = stm32x_info->part_info->block_size; From a99bf2ea9449d0e8120682feb2bedc398adab8b2 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Tue, 25 Feb 2020 19:35:44 +0100 Subject: [PATCH 180/354] semihosting: reorganize semihosting commands the same semihosting handlers chain is declared twice: 1. in src/target/armv4_5.c 2. in src/target/riscv/riscv.c to make it simpler we moved the declaration into 'src/target/semihosting_common.c' under semihosting_common_handlers[]. then we used this into both of armv4_5.c and riscv.c Change-Id: If813b3fd5eb2476658f1308f741c4e805141f617 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5473 Tested-by: jenkins Reviewed-by: Muhammad Omair Javaid Reviewed-by: Tim Newsome Reviewed-by: Liviu Ionescu --- src/target/armv4_5.c | 32 ++----------------------- src/target/riscv/riscv.c | 39 ++----------------------------- src/target/semihosting_common.c | 41 +++++++++++++++++++++++++++++---- 3 files changed, 40 insertions(+), 72 deletions(-) diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 7a72a0bf0..6c487626c 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -1098,10 +1098,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv) return JIM_OK; } -extern __COMMAND_HANDLER(handle_common_semihosting_command); -extern __COMMAND_HANDLER(handle_common_semihosting_fileio_command); -extern __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command); -extern __COMMAND_HANDLER(handle_common_semihosting_cmdline); +extern const struct command_registration semihosting_common_handlers[]; static const struct command_registration arm_exec_command_handlers[] = { { @@ -1140,32 +1137,7 @@ static const struct command_registration arm_exec_command_handlers[] = { .usage = "cpnum op1 CRn CRm op2", }, { - .name = "semihosting", - .handler = handle_common_semihosting_command, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable']", - .help = "activate support for semihosting operations", - }, - { - .name = "semihosting_cmdline", - .handler = handle_common_semihosting_cmdline, - .mode = COMMAND_EXEC, - .usage = "arguments", - .help = "command line arguments to be passed to program", - }, - { - .name = "semihosting_fileio", - .handler = handle_common_semihosting_fileio_command, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable']", - .help = "activate support for semihosting fileio operations", - }, - { - .name = "semihosting_resexit", - .handler = handle_common_semihosting_resumable_exit_command, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable']", - .help = "activate support for semihosting resumable exit", + .chain = semihosting_common_handlers, }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 1d6f66699..7ad1ccde9 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1887,11 +1887,6 @@ static const struct command_registration riscv_exec_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -extern __COMMAND_HANDLER(handle_common_semihosting_command); -extern __COMMAND_HANDLER(handle_common_semihosting_fileio_command); -extern __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command); -extern __COMMAND_HANDLER(handle_common_semihosting_cmdline); - /* * To be noted that RISC-V targets use the same semihosting commands as * ARM targets. @@ -1905,37 +1900,7 @@ extern __COMMAND_HANDLER(handle_common_semihosting_cmdline); * protocol, then a command like `riscv semihosting enable` will make * sense, but for now all semihosting commands are prefixed with `arm`. */ -static const struct command_registration arm_exec_command_handlers[] = { - { - .name = "semihosting", - .handler = handle_common_semihosting_command, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable']", - .help = "activate support for semihosting operations", - }, - { - .name = "semihosting_cmdline", - .handler = handle_common_semihosting_cmdline, - .mode = COMMAND_EXEC, - .usage = "arguments", - .help = "command line arguments to be passed to program", - }, - { - .name = "semihosting_fileio", - .handler = handle_common_semihosting_fileio_command, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable']", - .help = "activate support for semihosting fileio operations", - }, - { - .name = "semihosting_resexit", - .handler = handle_common_semihosting_resumable_exit_command, - .mode = COMMAND_EXEC, - .usage = "['enable'|'disable']", - .help = "activate support for semihosting resumable exit", - }, - COMMAND_REGISTRATION_DONE -}; +extern const struct command_registration semihosting_common_handlers[]; const struct command_registration riscv_command_handlers[] = { { @@ -1950,7 +1915,7 @@ const struct command_registration riscv_command_handlers[] = { .mode = COMMAND_ANY, .help = "ARM Command Group", .usage = "", - .chain = arm_exec_command_handlers + .chain = semihosting_common_handlers }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index a41f8e4c8..a02f2df3f 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -1461,7 +1461,7 @@ static void semihosting_set_field(struct target *target, uint64_t value, /* ------------------------------------------------------------------------- * Common semihosting commands handlers. */ -__COMMAND_HANDLER(handle_common_semihosting_command) +static __COMMAND_HANDLER(handle_common_semihosting_command) { struct target *target = get_current_target(CMD_CTX); @@ -1502,8 +1502,7 @@ __COMMAND_HANDLER(handle_common_semihosting_command) return ERROR_OK; } - -__COMMAND_HANDLER(handle_common_semihosting_fileio_command) +static __COMMAND_HANDLER(handle_common_semihosting_fileio_command) { struct target *target = get_current_target(CMD_CTX); @@ -1533,7 +1532,7 @@ __COMMAND_HANDLER(handle_common_semihosting_fileio_command) return ERROR_OK; } -__COMMAND_HANDLER(handle_common_semihosting_cmdline) +static __COMMAND_HANDLER(handle_common_semihosting_cmdline) { struct target *target = get_current_target(CMD_CTX); unsigned int i; @@ -1566,7 +1565,7 @@ __COMMAND_HANDLER(handle_common_semihosting_cmdline) return ERROR_OK; } -__COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command) +static __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command) { struct target *target = get_current_target(CMD_CTX); @@ -1595,3 +1594,35 @@ __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command) return ERROR_OK; } + +const struct command_registration semihosting_common_handlers[] = { + { + "semihosting", + .handler = handle_common_semihosting_command, + .mode = COMMAND_EXEC, + .usage = "['enable'|'disable']", + .help = "activate support for semihosting operations", + }, + { + "semihosting_cmdline", + .handler = handle_common_semihosting_cmdline, + .mode = COMMAND_EXEC, + .usage = "arguments", + .help = "command line arguments to be passed to program", + }, + { + "semihosting_fileio", + .handler = handle_common_semihosting_fileio_command, + .mode = COMMAND_EXEC, + .usage = "['enable'|'disable']", + .help = "activate support for semihosting fileio operations", + }, + { + "semihosting_resexit", + .handler = handle_common_semihosting_resumable_exit_command, + .mode = COMMAND_EXEC, + .usage = "['enable'|'disable']", + .help = "activate support for semihosting resumable exit", + }, + COMMAND_REGISTRATION_DONE +}; From 69f0105324f2fdcd0499ae07ada15d340762d061 Mon Sep 17 00:00:00 2001 From: "Anton V. Kirilchik" Date: Tue, 12 Mar 2019 23:11:39 +0300 Subject: [PATCH 181/354] Add target config for STM8S103 chip... Change-Id: I693e5b7933fc61956010a96be57ee6eb8abd3c31 Signed-off-by: Anton V. Kirilchik Reviewed-on: http://openocd.zylin.com/5422 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/target/stm8s103.cfg | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tcl/target/stm8s103.cfg diff --git a/tcl/target/stm8s103.cfg b/tcl/target/stm8s103.cfg new file mode 100644 index 000000000..714acf480 --- /dev/null +++ b/tcl/target/stm8s103.cfg @@ -0,0 +1,13 @@ +#config script for STM8S103 + +set FLASHEND 0x9FFF +set EEPROMEND 0x427F +set OPTIONEND 0x480A +set BLOCKSIZE 0x40 + +proc stm8_reset_rop {} { + mwb 0x4800 0x00 + reset halt +} + +source [find target/stm8s.cfg] From 9f4659ae6b246bcab77d915cee288b2307a926b3 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sat, 4 Nov 2017 09:47:02 +0100 Subject: [PATCH 182/354] target: add examine-fail event A configuration script may want to check the reason why examine fails e.g. device has security lock engaged. tcl/target/kx.cfg and klx.cfg is modified to use the new event for testing of the security lock of Kinetis MCU Change-Id: Id1d3a79d24e84b513f4ea35586cd2ab0437ff9b3 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4289 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 5 ++++- src/target/startup.tcl | 4 +++- src/target/target.c | 7 ++++++- src/target/target.h | 1 + tcl/target/klx.cfg | 6 +++--- tcl/target/kx.cfg | 8 ++++++-- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 454ae0675..711171a34 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4820,6 +4820,8 @@ The following target events are defined: @* Before target examine is called. @item @b{examine-end} @* After target examine is called with no errors. +@item @b{examine-fail} +@* After target examine fails. @item @b{gdb-attach} @* When GDB connects. Issued before any GDB communication with the target starts. GDB expects the target is halted during attachment. @@ -5991,7 +5993,8 @@ Used in kinetis 'fcf_source protection' mode only. @end deffn @deffn Command {kinetis mdm check_security} -Checks status of device security lock. Used internally in examine-end event. +Checks status of device security lock. Used internally in examine-end +and examine-fail event. @end deffn @deffn Command {kinetis mdm halt} diff --git a/src/target/startup.tcl b/src/target/startup.tcl index cf844e1f6..976cd2af5 100644 --- a/src/target/startup.tcl +++ b/src/target/startup.tcl @@ -66,7 +66,9 @@ proc ocd_process_reset_inner { MODE } { if {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} { $t invoke-event examine-start set err [catch "$t arp_examine allow-defer"] - if { $err == 0 } { + if { $err } { + $t invoke-event examine-fail + } else { $t invoke-event examine-end } } diff --git a/src/target/target.c b/src/target/target.c index 1ba4e0987..61ed9662d 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -219,6 +219,7 @@ static const Jim_Nvp nvp_target_event[] = { { .value = TARGET_EVENT_RESET_END, .name = "reset-end" }, { .value = TARGET_EVENT_EXAMINE_START, .name = "examine-start" }, + { .value = TARGET_EVENT_EXAMINE_FAIL, .name = "examine-fail" }, { .value = TARGET_EVENT_EXAMINE_END, .name = "examine-end" }, { .value = TARGET_EVENT_DEBUG_HALTED, .name = "debug-halted" }, @@ -708,13 +709,17 @@ static int default_check_reset(struct target *target) return ERROR_OK; } +/* Equvivalent Tcl code arp_examine_one is in src/target/startup.tcl + * Keep in sync */ int target_examine_one(struct target *target) { target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_START); int retval = target->type->examine(target); - if (retval != ERROR_OK) + if (retval != ERROR_OK) { + target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_FAIL); return retval; + } target_call_event_callbacks(target, TARGET_EVENT_EXAMINE_END); diff --git a/src/target/target.h b/src/target/target.h index 81fd9d23d..b954ec22d 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -275,6 +275,7 @@ enum target_event { TARGET_EVENT_DEBUG_RESUMED, /* target resumed to execute on behalf of the debugger */ TARGET_EVENT_EXAMINE_START, + TARGET_EVENT_EXAMINE_FAIL, TARGET_EVENT_EXAMINE_END, TARGET_EVENT_GDB_ATTACH, diff --git a/tcl/target/klx.cfg b/tcl/target/klx.cfg index 36b6ed596..84f6535e3 100644 --- a/tcl/target/klx.cfg +++ b/tcl/target/klx.cfg @@ -56,9 +56,9 @@ if {[using_hla]} { echo " it without mass erase. Don't set write protection on the first block." echo "!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!" echo "" -} { - # Detect secured MCU or boot lock-up in RESET/WDOG loop - $_CHIPNAME.cpu configure -event examine-start { +} else { + # Detect secured MCU + $_TARGETNAME configure -event examine-fail { kinetis mdm check_security } diff --git a/tcl/target/kx.cfg b/tcl/target/kx.cfg index 0ff5b0c53..1dd5d316c 100644 --- a/tcl/target/kx.cfg +++ b/tcl/target/kx.cfg @@ -58,9 +58,13 @@ if {[using_hla]} { echo " it without mass erase. Don't set write protection on the first block." echo "!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!" echo "" -} { +} else { # Detect secured MCU or boot lock-up in RESET/WDOG loop - $_CHIPNAME.cpu configure -event examine-start { + $_TARGETNAME configure -event examine-fail { + kinetis mdm check_security + } + # During RESET/WDOG loop the target is sometimes falsely examined + $_TARGETNAME configure -event examine-end { kinetis mdm check_security } From 4845b5437284b964aad40b1cec57324732abb4d5 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 9 Dec 2019 12:35:01 +0100 Subject: [PATCH 183/354] target/aarch64: fix minor stepping issue with gdb when using step command from gdb the step happens without any issue, but aarch64_step call explicitly aarch64_poll which consumes the status change to HALTED, so it does not inform gdb that the step has finished. by removing this call, all is back to normal and openocd could inform gdb that the step has finished. Change-Id: I9366aecd20f7d52259b050b8653189b67d9299d0 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5354 Tested-by: jenkins Reviewed-by: Muhammad Omair Javaid Reviewed-by: Antonio Borneo --- src/target/aarch64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 7acb4726a..4d3d9819e 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -1176,7 +1176,7 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres if (saved_retval != ERROR_OK) return saved_retval; - return aarch64_poll(target); + return ERROR_OK; } static int aarch64_restore_context(struct target *target, bool bpwp) From a154973896576ae59952785e7b2137fb17dac7da Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Wed, 4 Dec 2019 15:09:51 +0100 Subject: [PATCH 184/354] target/aarch64: fix soft breakpoint when PE is in AArch32 state Before this patch aarch64_set_breakpoint was using either A64, or A32 HLT opcode by relying on armv8_opcode helper. This behaviors ignores the fact that in AArch32 state the core could execute Thumb-2 instructions, and gdb could request to insert a soft bkpt in a Thumb-2 code chunk. In this change, we check the core_state and bkpt length to know the correct opcode to use. Note: based on https://sourceware.org/gdb/current/onlinedocs/gdb/ARM-Breakpoint-Kinds.html if bkpt length/kind == 3, we should replace a 32-bit Thumb-2 opcode, then we use twice the 16 bits Thumb-2 bkpt opcode and we fix-up the length to 4 bytes, in order to set correctly the bpkt. Change-Id: I8f3551124412c61d155eae87761767e9937f917d Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5355 Tested-by: jenkins Reviewed-by: Muhammad Omair Javaid Reviewed-by: Antonio Borneo --- src/target/aarch64.c | 25 ++++++++++++++++++++++++- src/target/armv8_opcodes.h | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 4d3d9819e..3918b1575 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -1263,9 +1263,32 @@ static int aarch64_set_breakpoint(struct target *target, brp_list[brp_i].value); } else if (breakpoint->type == BKPT_SOFT) { + uint32_t opcode; uint8_t code[4]; - buf_set_u32(code, 0, 32, armv8_opcode(armv8, ARMV8_OPC_HLT)); + if (armv8_dpm_get_core_state(&armv8->dpm) == ARM_STATE_AARCH64) { + opcode = ARMV8_HLT(11); + + if (breakpoint->length != 4) + LOG_ERROR("bug: breakpoint length should be 4 in AArch64 mode"); + } else { + /** + * core_state is ARM_STATE_ARM + * in that case the opcode depends on breakpoint length: + * - if length == 4 => A32 opcode + * - if length == 2 => T32 opcode + * - if length == 3 => T32 opcode (refer to gdb doc : ARM-Breakpoint-Kinds) + * in that case the length should be changed from 3 to 4 bytes + **/ + opcode = (breakpoint->length == 4) ? ARMV8_HLT_A1(11) : + (uint32_t) (ARMV8_HLT_T1(11) | ARMV8_HLT_T1(11) << 16); + + if (breakpoint->length == 3) + breakpoint->length = 4; + } + + buf_set_u32(code, 0, 32, opcode); + retval = target_read_memory(target, breakpoint->address & 0xFFFFFFFFFFFFFFFE, breakpoint->length, 1, diff --git a/src/target/armv8_opcodes.h b/src/target/armv8_opcodes.h index 3fda29668..217cc64c6 100644 --- a/src/target/armv8_opcodes.h +++ b/src/target/armv8_opcodes.h @@ -153,6 +153,7 @@ #define ARMV8_BKPT(Im) (0xD4200000 | ((Im & 0xffff) << 5)) #define ARMV8_HLT(Im) (0x0D4400000 | ((Im & 0xffff) << 5)) #define ARMV8_HLT_A1(Im) (0xE1000070 | ((Im & 0xFFF0) << 4) | (Im & 0xF)) +#define ARMV8_HLT_T1(Im) (0xba80 | (Im & 0x3f)) #define ARMV8_MOVFSP_64(Rt) ((1 << 31) | 0x11000000 | (0x1f << 5) | (Rt)) #define ARMV8_MOVTSP_64(Rt) ((1 << 31) | 0x11000000 | (Rt << 5) | (0x1F)) From a8b1bd8376ad30e8ffe7d4d87ed0b041d7adbe76 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 9 Dec 2019 12:47:07 +0100 Subject: [PATCH 185/354] target/armv8_opcodes: use T32 instructions when the PE is in AArch32 state As stated in ARM v8-A Architecture Reference Manual (ARM DDI 0487E.a) in Chapter H4.3 DCC and ITR access modes: Writes to EDITR trigger the instruction to be executed if the PE is in Debug state: - If the PE is in AArch64 state, this is an A64 instruction. - If the PE is in AArch32 state, this is a T32 instruction But in armv8_opcodes specifically in t32_opcodes we were using some A32 instructions for HLT, LDRx and STRx opcodes. Using the correct LDRx and STRx opcodes, fixes 16 and 8 bits memory access when the PE is in AArch32 state. Change-Id: Ib1acbdd4966297e7b069569bcb8deea3c3993615 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5346 Tested-by: jenkins Reviewed-by: Muhammad Omair Javaid Reviewed-by: Antonio Borneo --- src/target/armv8_opcodes.c | 14 +++++++------- src/target/armv8_opcodes.h | 8 ++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/target/armv8_opcodes.c b/src/target/armv8_opcodes.c index 6887b2953..96db72871 100644 --- a/src/target/armv8_opcodes.c +++ b/src/target/armv8_opcodes.c @@ -68,13 +68,13 @@ static const uint32_t t32_opcodes[ARMV8_OPC_NUM] = { [ARMV8_OPC_DCCISW] = ARMV4_5_MCR(15, 0, 0, 7, 14, 2), [ARMV8_OPC_DCCIVAC] = ARMV4_5_MCR(15, 0, 0, 7, 14, 1), [ARMV8_OPC_ICIVAU] = ARMV4_5_MCR(15, 0, 0, 7, 5, 1), - [ARMV8_OPC_HLT] = ARMV8_HLT_A1(11), - [ARMV8_OPC_LDRB_IP] = ARMV4_5_LDRB_IP(1, 0), - [ARMV8_OPC_LDRH_IP] = ARMV4_5_LDRH_IP(1, 0), - [ARMV8_OPC_LDRW_IP] = ARMV4_5_LDRW_IP(1, 0), - [ARMV8_OPC_STRB_IP] = ARMV4_5_STRB_IP(1, 0), - [ARMV8_OPC_STRH_IP] = ARMV4_5_STRH_IP(1, 0), - [ARMV8_OPC_STRW_IP] = ARMV4_5_STRW_IP(1, 0), + [ARMV8_OPC_HLT] = ARMV8_HLT_T1(11), + [ARMV8_OPC_LDRB_IP] = ARMV8_LDRB_IP_T3(1, 0), + [ARMV8_OPC_LDRH_IP] = ARMV8_LDRH_IP_T3(1, 0), + [ARMV8_OPC_LDRW_IP] = ARMV8_LDRW_IP_T3(1, 0), + [ARMV8_OPC_STRB_IP] = ARMV8_STRB_IP_T3(1, 0), + [ARMV8_OPC_STRH_IP] = ARMV8_STRH_IP_T3(1, 0), + [ARMV8_OPC_STRW_IP] = ARMV8_STRW_IP_T3(1, 0), }; void armv8_select_opcodes(struct armv8_common *armv8, bool state_is_aarch64) diff --git a/src/target/armv8_opcodes.h b/src/target/armv8_opcodes.h index 217cc64c6..239c4c5f1 100644 --- a/src/target/armv8_opcodes.h +++ b/src/target/armv8_opcodes.h @@ -164,10 +164,18 @@ #define ARMV8_LDRH_IP(Rd, Rn) (0x78402400 | (Rn << 5) | Rd) #define ARMV8_LDRW_IP(Rd, Rn) (0xb8404400 | (Rn << 5) | Rd) +#define ARMV8_LDRB_IP_T3(Rd, Rn) (0xf8100b01 | (Rn << 16) | (Rd << 12)) +#define ARMV8_LDRH_IP_T3(Rd, Rn) (0xf8300b02 | (Rn << 16) | (Rd << 12)) +#define ARMV8_LDRW_IP_T3(Rd, Rn) (0xf8500b04 | (Rn << 16) | (Rd << 12)) + #define ARMV8_STRB_IP(Rd, Rn) (0x38001400 | (Rn << 5) | Rd) #define ARMV8_STRH_IP(Rd, Rn) (0x78002400 | (Rn << 5) | Rd) #define ARMV8_STRW_IP(Rd, Rn) (0xb8004400 | (Rn << 5) | Rd) +#define ARMV8_STRB_IP_T3(Rd, Rn) (0xf8000b01 | (Rn << 16) | (Rd << 12)) +#define ARMV8_STRH_IP_T3(Rd, Rn) (0xf8200b02 | (Rn << 16) | (Rd << 12)) +#define ARMV8_STRW_IP_T3(Rd, Rn) (0xf8400b04 | (Rn << 16) | (Rd << 12)) + #define ARMV8_MOV_GPR_VFP(Rd, Rn, Index) (0x4e083c00 | (Index << 20) | (Rn << 5) | Rd) #define ARMV8_MOV_VFP_GPR(Rd, Rn, Index) (0x4e081c00 | (Index << 20) | (Rn << 5) | Rd) From afe899f938a8edb3657c9455fc5caefcaef7e65f Mon Sep 17 00:00:00 2001 From: Matthias Welwarsky Date: Thu, 11 Apr 2019 10:22:27 +0200 Subject: [PATCH 186/354] cortex_a: warn on broken debug_base setting A common problem with target configurations appears to be broken debug base address configuration. ARM DDI0406C.d specifies in App. D, 1.4.1, that bit 31 of the debug base address serves as identification of an external debugger, as opposed to an internal access to memory mapped debug registers by the CPU. External accesses are treated as privileged and require no debug authentification via the lock access register. Sometimes the base address of a debug component is wrong even in the targets' ROM table. In this case, the correct base address must be specified using the -dbgbase argument when creating the target. This patch adds a warning when bit 31 of the debug base address is not set, as a hint to the user. Change-Id: I9c41d85a138123c657ef655e3436a2aa39249dcc Signed-off-by: Matthias Welwarsky Reviewed-on: http://openocd.zylin.com/5105 Tested-by: jenkins Reviewed-by: Tommy Vestermark Reviewed-by: Antonio Borneo --- src/target/cortex_a.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 8773ea160..a79b0b906 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -2718,6 +2718,10 @@ static int cortex_a_examine_first(struct target *target) } else armv7a->debug_base = target->dbgbase; + if ((armv7a->debug_base & (1UL<<31)) == 0) + LOG_WARNING("Debug base address for target %s has bit 31 set to 0. Access to debug registers will likely fail!\n" + "Please fix the target configuration.", target_name(target)); + retval = mem_ap_read_atomic_u32(armv7a->debug_ap, armv7a->debug_base + CPUDBG_DIDR, &didr); if (retval != ERROR_OK) { From 221fe49879607096acad42c9db9f68f852a2fbe7 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Tue, 25 Feb 2020 19:44:58 +0100 Subject: [PATCH 187/354] semihosting: add semihosting handlers to AArch64 note: this works only when the PE is in AArch64 state Change-Id: Id6a336ca7d201df72bd1aaaeccce4185473fc1bd Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5474 Tested-by: jenkins Reviewed-by: Muhammad Omair Javaid Reviewed-by: Antonio Borneo --- src/target/aarch64.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 3918b1575..87176f638 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2782,7 +2782,16 @@ static const struct command_registration aarch64_exec_command_handlers[] = { COMMAND_REGISTRATION_DONE }; +extern const struct command_registration semihosting_common_handlers[]; + static const struct command_registration aarch64_command_handlers[] = { + { + .name = "arm", + .mode = COMMAND_ANY, + .help = "ARM Command Group", + .usage = "", + .chain = semihosting_common_handlers + }, { .chain = armv8_command_handlers, }, From 44967a9e07ff01a01a96757f302c053553cff35e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 24 Feb 2020 12:26:07 +0100 Subject: [PATCH 188/354] jtag: report API reset as synchronous The jtag API reset() is synchronous, but this was not highlighted in the description. Change-Id: I76ffb7eec97c8608cfbef0b9268ee18a5f50b221 Signed-off-by: Antonio Borneo Fixes: 8850eb8f2c51 ("swd: get rid of jtag queue to assert/deassert srst") Reviewed-on: http://openocd.zylin.com/5471 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/jtag/interface.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/jtag/interface.h b/src/jtag/interface.h index f4c6a98ba..39d2d9d88 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -250,6 +250,8 @@ struct adapter_driver { /** * Control (assert/deassert) the signals SRST and TRST on the interface. + * This function is synchronous and should be called after the adapter + * queue has been properly flushed. * This function is optional. * Adapters that don't support resets can either not define this function * or return an error code. From 939febeccafc885d3869ce94c688aaf724f2eccd Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 14 Feb 2020 14:35:51 +0100 Subject: [PATCH 189/354] target: fix crash with jimtcl 0.78 The jimtcl commit 41c5ff1809f5 ("jim.c: Fix Object leak in zlib support") https://repo.or.cz/jimtcl.git/commit/41c5ff1809f5 makes Jim_SetResultFormatted() freeing the parameters that have zero refcount. OpenOCD commit 559d08c19ed8 ("jim tests: use installed") adds the only code instance in OpenOCD that first passes a zero refcount object to Jim_SetResultFormatted() and then frees it. By switching jimtcl version to 0.78 or newer this causes a crash of OpenOCD. To trigger the crash in a telnet session, check that the current target is running and type: [target current] arp_waitstate halted 1 Remove the call to Jim_FreeNewObj() after the call to Jim_SetResultFormatted(). Change-Id: I5f5a8bca96a0e8466ff7b789fe578ea9785fa550 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5453 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/target/target.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/target/target.c b/src/target/target.c index 61ed9662d..ceecaee10 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5164,7 +5164,6 @@ static int jim_target_wait_state(Jim_Interp *interp, int argc, Jim_Obj *const *a "target: %s wait %s fails (%#s) %s", target_name(target), n->name, eObj, target_strerror_safe(e)); - Jim_FreeNewObj(interp, eObj); return JIM_ERR; } return JIM_OK; From 2e1dfebc8e62376e0ae3e55ac776149bed462330 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 19 Oct 2019 19:46:53 +0200 Subject: [PATCH 190/354] jimtcl: update to tag 0.79 OpenOCD is stuck at jimtcl tag 0.77 that is 3 years old. The latest tag 0.79 (2019-11-20) is already used by debian build, which packs jim library separately, as shown in [1]. Today only the build for architecture powerpcspe is still not updated to latest package version. I have been using jim 0.79 since the day of the release, without any issue. Switch jimtcl to latest tag 0.79 [1] https://packages.debian.org/sid/openocd Change-Id: I3426e68c32f88ecde74d4278303925423db451e0 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5403 Tested-by: jenkins Reviewed-by: Tomas Vanek --- jimtcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jimtcl b/jimtcl index a9bf5975f..0aa0fb4e3 160000 --- a/jimtcl +++ b/jimtcl @@ -1 +1 @@ -Subproject commit a9bf5975fd0f89974d689a2d9ebd0873c8d64787 +Subproject commit 0aa0fb4e3a38d38a49de9eb585d93d63a370dcf6 From fbbfbb2516a58b2ab866d713ef18c0a210bb647b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 3 Feb 2020 16:48:40 +0100 Subject: [PATCH 191/354] ftdi: flush mpsse queue after a level change on reset pins The function ftdi_set_signal() does not propagate the pin change until next call to mpsse_flush(). Current code does not toggles immediately the reset pins if polling is turned off. Call mpsse_flush() at the end of ftdi_reset(). While there, remove the duplicated LOG message. Change-Id: I79eacfe4fc32b5cdf2dc1b78f3660d96988466bc Fixes: 8850eb8f2c51 ("swd: get rid of jtag queue to assert/deassert srst") Reported-by: Leonard Crestez Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5431 Tested-by: jenkins Reviewed-by: Leonard Crestez Reviewed-by: Tomas Vanek --- src/jtag/drivers/ftdi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index a9cdbbe1e..121cb469f 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -550,8 +550,7 @@ static int ftdi_reset(int trst, int srst) ftdi_set_signal(sig_nsrst, 'z'); } - LOG_DEBUG_IO("trst: %i, srst: %i", trst, srst); - return ERROR_OK; + return mpsse_flush(mpsse_ctx); } static void ftdi_execute_sleep(struct jtag_command *cmd) From f447c31b30f805725b7a09d51d786c88de4b7a4f Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 24 Jun 2019 12:17:17 +0200 Subject: [PATCH 192/354] arm: fix reg num for Monitor mode Commit 2efb1f14f611 ("Add GDB remote target description support for ARM4") inserts two additional registers "sp" and "lr" in the table arm_core_regs[], thus shifting by two the position of the last three registers already present "sp_mon" moved from index 37 to 39 "lr_mon" moved from index 38 to 40 "spsr_mon" moved from index 39 to 41 Part of the code is updated (e.g. enum defining ARM_SPSR_MON and array arm_mon_indices[]), but it's missing the update of mapping in armv4_5_core_reg_map[]. Fix armv4_5_core_reg_map[]. Change-Id: I0bdf766183392eb738206b876cd9559aacc29fa0 Signed-off-by: Antonio Borneo Fixes: 2efb1f14f611 ("Add GDB remote target description support for ARM4") Reviewed-on: http://openocd.zylin.com/5257 Tested-by: jenkins --- src/target/armv4_5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 6c487626c..6d0385715 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -414,7 +414,7 @@ const int armv4_5_core_reg_map[8][17] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31 }, { /* MON */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 37, 38, 15, 39, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 39, 40, 15, 41, } }; From fba438fde7355bcbe5fb4dc0ce712665d3d8a6da Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 24 Jun 2019 17:15:33 +0200 Subject: [PATCH 193/354] arm: Use different enum for core_type and core_mode The fields core_type and core_mode use the same enum arm_mode but encode different information, making the code less immediate to read. Use a different enum arm_core_type for the field core_type. The code behavior is not changed. Change-Id: I60f2095ea6801dfe22f6da81ec295ca71ef90466 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5258 Tested-by: jenkins --- src/target/arm.h | 27 ++++++++++++++++++--------- src/target/arm11.c | 4 ++-- src/target/arm7_9_common.c | 2 +- src/target/armv4_5.c | 18 +++++++++--------- src/target/armv7m.c | 2 +- src/target/cortex_a.c | 2 +- src/target/xscale.c | 2 +- 7 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/target/arm.h b/src/target/arm.h index ea83d3867..bf0d9327e 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -40,6 +40,22 @@ * support has not yet been integrated, affecting Cortex-M parts. */ +/** + * Indicates what registers are in the ARM state core register set. + * + * - ARM_CORE_TYPE_STD indicates the standard set of 37 registers, seen + * on for example ARM7TDMI cores. + * - ARM_CORE_TYPE_SEC_EXT indicates core has security extensions, thus + * three more registers are shadowed for "Secure Monitor" mode. + * - ARM_CORE_TYPE_M_PROFILE indicates a microcontroller profile core, + * which only shadows SP. + */ +enum arm_core_type { + ARM_CORE_TYPE_STD = -1, + ARM_CORE_TYPE_SEC_EXT = 1, + ARM_CORE_TYPE_M_PROFILE, +}; + /** * Represent state of an ARM core. * @@ -161,15 +177,8 @@ struct arm { /** Support for arm_reg_current() */ const int *map; - /** - * Indicates what registers are in the ARM state core register set. - * ARM_MODE_ANY indicates the standard set of 37 registers, - * seen on for example ARM7TDMI cores. ARM_MODE_MON indicates three - * more registers are shadowed, for "Secure Monitor" mode. - * ARM_MODE_THREAD indicates a microcontroller profile core, - * which only shadows SP. - */ - enum arm_mode core_type; + /** Indicates what registers are in the ARM state core register set. */ + enum arm_core_type core_type; /** Record the current core mode: SVC, USR, or some other mode. */ enum arm_mode core_mode; diff --git a/src/target/arm11.c b/src/target/arm11.c index 159c30a85..51f2a337a 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -1109,7 +1109,7 @@ static int arm11_target_create(struct target *target, Jim_Interp *interp) if (!arm11) return ERROR_FAIL; - arm11->arm.core_type = ARM_MODE_ANY; + arm11->arm.core_type = ARM_CORE_TYPE_STD; arm_init_arch_info(target, &arm11->arm); arm11->jtag_info.tap = target->tap; @@ -1180,7 +1180,7 @@ static int arm11_examine(struct target *target) type = "ARM1156"; break; case 0x7B76: - arm11->arm.core_type = ARM_MODE_MON; + arm11->arm.core_type = ARM_CORE_TYPE_SEC_EXT; /* NOTE: could default arm11->hardware_step to true */ type = "ARM1176"; break; diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index b2962d1c4..6a7bf9da5 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2848,7 +2848,7 @@ int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9) arm7_9->dcc_downloads = false; arm->arch_info = arm7_9; - arm->core_type = ARM_MODE_ANY; + arm->core_type = ARM_CORE_TYPE_STD; arm->read_core_reg = arm7_9_read_core_reg; arm->write_core_reg = arm7_9_write_core_reg; arm->full_context = arm7_9_full_context; diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 6d0385715..266a45869 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -658,7 +658,7 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm) for (i = 0; i < num_core_regs; i++) { /* Skip registers this core doesn't expose */ if (arm_core_regs[i].mode == ARM_MODE_MON - && arm->core_type != ARM_MODE_MON) + && arm->core_type != ARM_CORE_TYPE_SEC_EXT) continue; /* REVISIT handle Cortex-M, which only shadows R13/SP */ @@ -787,7 +787,7 @@ COMMAND_HANDLER(handle_armv4_5_reg_command) return ERROR_FAIL; } - if (arm->core_type != ARM_MODE_ANY) { + if (arm->core_type != ARM_CORE_TYPE_STD) { command_print(CMD, "Microcontroller Profile not supported - use standard reg cmd"); return ERROR_OK; @@ -820,7 +820,7 @@ COMMAND_HANDLER(handle_armv4_5_reg_command) sep = ""; break; case ARM_MODE_MON: - if (arm->core_type != ARM_MODE_MON) + if (arm->core_type != ARM_CORE_TYPE_SEC_EXT) continue; /* FALLTHROUGH */ default: @@ -872,7 +872,7 @@ COMMAND_HANDLER(handle_armv4_5_core_state_command) return ERROR_FAIL; } - if (arm->core_type == ARM_MODE_THREAD) { + if (arm->core_type == ARM_CORE_TYPE_M_PROFILE) { /* armv7m not supported */ command_print(CMD, "Unsupported Command"); return ERROR_OK; @@ -910,7 +910,7 @@ COMMAND_HANDLER(handle_arm_disassemble_command) return ERROR_FAIL; } - if (arm->core_type == ARM_MODE_THREAD) { + if (arm->core_type == ARM_CORE_TYPE_M_PROFILE) { /* armv7m is always thumb mode */ thumb = 1; } @@ -1197,7 +1197,7 @@ int arm_get_gdb_reg_list(struct target *target, break; case REG_CLASS_ALL: - *reg_list_size = (arm->core_type != ARM_MODE_MON ? 48 : 51); + *reg_list_size = (arm->core_type != ARM_CORE_TYPE_SEC_EXT ? 48 : 51); unsigned int list_size_core = *reg_list_size; if (arm->arm_vfp_version == ARM_VFP_V3) *reg_list_size += 33; @@ -1210,7 +1210,7 @@ int arm_get_gdb_reg_list(struct target *target, for (i = 13; i < ARRAY_SIZE(arm_core_regs); i++) { int reg_index = arm->core_cache->reg_list[i].number; if (!(arm_core_regs[i].mode == ARM_MODE_MON - && arm->core_type != ARM_MODE_MON)) + && arm->core_type != ARM_CORE_TYPE_SEC_EXT)) (*reg_list)[reg_index] = &(arm->core_cache->reg_list[i]); } @@ -1673,8 +1673,8 @@ int arm_init_arch_info(struct target *target, struct arm *arm) arm->common_magic = ARM_COMMON_MAGIC; /* core_type may be overridden by subtype logic */ - if (arm->core_type != ARM_MODE_THREAD) { - arm->core_type = ARM_MODE_ANY; + if (arm->core_type != ARM_CORE_TYPE_M_PROFILE) { + arm->core_type = ARM_CORE_TYPE_STD; arm_set_cpsr(arm, ARM_MODE_USR); } diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 4b37774a5..82d6e6307 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -695,7 +695,7 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m) /* Enable stimulus port #0 by default */ armv7m->trace_config.itm_ter[0] = 1; - arm->core_type = ARM_MODE_THREAD; + arm->core_type = ARM_CORE_TYPE_M_PROFILE; arm->arch_info = armv7m; arm->setup_semihosting = armv7m_setup_semihosting; diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index a79b0b906..4f351f04a 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -2787,7 +2787,7 @@ static int cortex_a_examine_first(struct target *target) } } - armv7a->arm.core_type = ARM_MODE_MON; + armv7a->arm.core_type = ARM_CORE_TYPE_SEC_EXT; /* Avoid recreating the registers cache */ if (!target_was_examined(target)) { diff --git a/src/target/xscale.c b/src/target/xscale.c index e57996585..f879a9cc9 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -2981,7 +2981,7 @@ static int xscale_init_arch_info(struct target *target, /* prepare ARMv4/5 specific information */ arm->arch_info = xscale; - arm->core_type = ARM_MODE_ANY; + arm->core_type = ARM_CORE_TYPE_STD; arm->read_core_reg = xscale_read_core_reg; arm->write_core_reg = xscale_write_core_reg; arm->full_context = xscale_full_context; From 9626402c5a65423d4e4e9091f710b542522ca125 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 24 Jun 2019 18:45:11 +0200 Subject: [PATCH 194/354] target/armv4_5: remove unused macro The macro ARMV4_5_CORE_REG_MODENUM() is unused. Remove it! Change-Id: I183df57bd86c9428710ea3583e43fba88fd26e0a Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5260 Tested-by: jenkins Reviewed-by: Muhammad Omair Javaid --- src/target/armv4_5.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 266a45869..c27e9537d 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -768,9 +768,6 @@ int arm_arch_state(struct target *target) return ERROR_OK; } -#define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \ - (cache->reg_list[armv4_5_core_reg_map[mode][num]]) - COMMAND_HANDLER(handle_armv4_5_reg_command) { struct target *target = get_current_target(CMD_CTX); From 6900c5af4ec3f6df52227169d7d897eb14a44bca Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 24 Jun 2019 18:28:31 +0200 Subject: [PATCH 195/354] armv7a: access monitor registers only with security extensions Accordingly to ARM DDI 0406C at B1.5, the security extensions for armv7a are optional extensions and can be detected by reading ID_PFR1. The monitor mode is part of the security extensions and the shadow registers "sp_mon", "lr_mon" and "spsr_mon" are only present with the security extensions. Read the register ID_PFR1 during cortex_a examine, determine if security extension is present and then conditionally enable the visibility of the monitor mode shadow registers. Change-Id: Ib4834698659046566f6dc5cd35b44de122dc02e5 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5259 Tested-by: jenkins --- src/target/armv7a.h | 3 +++ src/target/cortex_a.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/target/armv7a.h b/src/target/armv7a.h index 0ef04c162..3d88c8679 100644 --- a/src/target/armv7a.h +++ b/src/target/armv7a.h @@ -178,6 +178,9 @@ static inline bool is_armv7a(struct armv7a_common *armv7a) /* See ARMv7a arch spec section C10.8 */ #define CPUDBG_AUTHSTATUS 0xFB8 +/* See ARMv7a arch spec DDI 0406C C11.10 */ +#define CPUDBG_ID_PFR1 0xD24 + /* Masks for Vector Catch register */ #define DBG_VCR_FIQ_MASK ((1 << 31) | (1 << 7)) #define DBG_VCR_IRQ_MASK ((1 << 30) | (1 << 6)) diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 4f351f04a..22cbc3d06 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -2678,7 +2678,7 @@ static int cortex_a_examine_first(struct target *target) int i; int retval = ERROR_OK; - uint32_t didr, cpuid, dbg_osreg; + uint32_t didr, cpuid, dbg_osreg, dbg_idpfr1; /* Search for the APB-AP - it is needed for access to debug registers */ retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap); @@ -2787,7 +2787,16 @@ static int cortex_a_examine_first(struct target *target) } } - armv7a->arm.core_type = ARM_CORE_TYPE_SEC_EXT; + retval = mem_ap_read_atomic_u32(armv7a->debug_ap, + armv7a->debug_base + CPUDBG_ID_PFR1, &dbg_idpfr1); + if (retval != ERROR_OK) + return retval; + + if (dbg_idpfr1 & 0x000000f0) { + LOG_DEBUG("target->coreid %" PRId32 " has security extensions", + target->coreid); + armv7a->arm.core_type = ARM_CORE_TYPE_SEC_EXT; + } /* Avoid recreating the registers cache */ if (!target_was_examined(target)) { From b5d2b1224fed3909aa3314339611ac5ac7ab0f82 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 25 Jun 2019 16:01:38 +0200 Subject: [PATCH 196/354] target/cortex_a: add hypervisor mode Hypervisor mode is present only if the optional virtualization extensions are available. Moreover, virtualization extensions require that also security extensions are implemented. Add the required infrastructure for the shadowed registers in hypervisor mode. Make monitor shadowed registers visible in hypervisor mode too. Make hypervisor shadowed registers visible in hypervisor mode only. Check during cortex_a examine if virtualization extensions are present and then conditionally enable the visibility of both hypervisor and monitor modes shadowed registers. Change-Id: I81dbb1ee8baf4c9f1a2226b77c10c8a2a7b34871 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5261 Tested-by: jenkins --- src/target/arm.h | 5 ++++ src/target/armv4_5.c | 61 ++++++++++++++++++++++++++++++++++++++----- src/target/armv4_5.h | 2 +- src/target/cortex_a.c | 9 +++++++ 4 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/target/arm.h b/src/target/arm.h index bf0d9327e..b39957495 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -47,12 +47,16 @@ * on for example ARM7TDMI cores. * - ARM_CORE_TYPE_SEC_EXT indicates core has security extensions, thus * three more registers are shadowed for "Secure Monitor" mode. + * - ARM_CORE_TYPE_VIRT_EXT indicates core has virtualization extensions + * and also security extensions. Additional shadowed registers for + * "Secure Monitor" and "Hypervisor" modes. * - ARM_CORE_TYPE_M_PROFILE indicates a microcontroller profile core, * which only shadows SP. */ enum arm_core_type { ARM_CORE_TYPE_STD = -1, ARM_CORE_TYPE_SEC_EXT = 1, + ARM_CORE_TYPE_VIRT_EXT, ARM_CORE_TYPE_M_PROFILE, }; @@ -76,6 +80,7 @@ enum arm_mode { ARM_MODE_SVC = 19, ARM_MODE_MON = 22, ARM_MODE_ABT = 23, + ARM_MODE_HYP = 26, ARM_MODE_UND = 27, ARM_MODE_1176_MON = 28, ARM_MODE_SYS = 31, diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index c27e9537d..a0983cd54 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -48,6 +48,7 @@ enum { ARMV4_5_SPSR_ABT = 35, ARMV4_5_SPSR_UND = 36, ARM_SPSR_MON = 41, + ARM_SPSR_HYP = 43, }; static const uint8_t arm_usr_indices[17] = { @@ -78,6 +79,10 @@ static const uint8_t arm_mon_indices[3] = { 39, 40, ARM_SPSR_MON, }; +static const uint8_t arm_hyp_indices[2] = { + 42, ARM_SPSR_HYP, +}; + static const struct { const char *name; unsigned short psr; @@ -163,6 +168,14 @@ static const struct { .name = "Handler", .psr = ARM_MODE_HANDLER, }, + + /* armv7-a with virtualization extension */ + { + .name = "Hypervisor", + .psr = ARM_MODE_HYP, + .n_indices = ARRAY_SIZE(arm_hyp_indices), + .indices = arm_hyp_indices, + }, }; /** Map PSR mode bits to the name of an ARM processor operating mode. */ @@ -209,6 +222,8 @@ int arm_mode_to_number(enum arm_mode mode) case ARM_MODE_MON: case ARM_MODE_1176_MON: return 7; + case ARM_MODE_HYP: + return 8; default: LOG_ERROR("invalid mode value encountered %d", mode); return -1; @@ -235,6 +250,8 @@ enum arm_mode armv4_5_number_to_mode(int number) return ARM_MODE_SYS; case 7: return ARM_MODE_MON; + case 8: + return ARM_MODE_HYP; default: LOG_ERROR("mode index out of bounds %d", number); return ARM_MODE_ANY; @@ -342,6 +359,9 @@ static const struct { [40] = { .name = "lr_mon", .cookie = 14, .mode = ARM_MODE_MON, .gdb_index = 49, }, [41] = { .name = "spsr_mon", .cookie = 16, .mode = ARM_MODE_MON, .gdb_index = 50, }, + /* These exist only when the Virtualization Extensions is present */ + [42] = { .name = "sp_hyp", .cookie = 13, .mode = ARM_MODE_HYP, .gdb_index = 51, }, + [43] = { .name = "spsr_hyp", .cookie = 16, .mode = ARM_MODE_HYP, .gdb_index = 52, }, }; static const struct { @@ -391,7 +411,7 @@ static const struct { /* map core mode (USR, FIQ, ...) and register number to * indices into the register cache */ -const int armv4_5_core_reg_map[8][17] = { +const int armv4_5_core_reg_map[9][17] = { { /* USR */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31 }, @@ -415,6 +435,9 @@ const int armv4_5_core_reg_map[8][17] = { }, { /* MON */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 39, 40, 15, 41, + }, + { /* HYP */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 42, 14, 15, 43, } }; @@ -658,7 +681,11 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm) for (i = 0; i < num_core_regs; i++) { /* Skip registers this core doesn't expose */ if (arm_core_regs[i].mode == ARM_MODE_MON - && arm->core_type != ARM_CORE_TYPE_SEC_EXT) + && arm->core_type != ARM_CORE_TYPE_SEC_EXT + && arm->core_type != ARM_CORE_TYPE_VIRT_EXT) + continue; + if (arm_core_regs[i].mode == ARM_MODE_HYP + && arm->core_type != ARM_CORE_TYPE_VIRT_EXT) continue; /* REVISIT handle Cortex-M, which only shadows R13/SP */ @@ -816,8 +843,13 @@ COMMAND_HANDLER(handle_armv4_5_reg_command) name = "System and User"; sep = ""; break; + case ARM_MODE_HYP: + if (arm->core_type != ARM_CORE_TYPE_VIRT_EXT) + continue; + /* FALLTHROUGH */ case ARM_MODE_MON: - if (arm->core_type != ARM_CORE_TYPE_SEC_EXT) + if (arm->core_type != ARM_CORE_TYPE_SEC_EXT + && arm->core_type != ARM_CORE_TYPE_VIRT_EXT) continue; /* FALLTHROUGH */ default: @@ -1194,7 +1226,16 @@ int arm_get_gdb_reg_list(struct target *target, break; case REG_CLASS_ALL: - *reg_list_size = (arm->core_type != ARM_CORE_TYPE_SEC_EXT ? 48 : 51); + switch (arm->core_type) { + case ARM_CORE_TYPE_SEC_EXT: + *reg_list_size = 51; + break; + case ARM_CORE_TYPE_VIRT_EXT: + *reg_list_size = 53; + break; + default: + *reg_list_size = 48; + } unsigned int list_size_core = *reg_list_size; if (arm->arm_vfp_version == ARM_VFP_V3) *reg_list_size += 33; @@ -1206,9 +1247,15 @@ int arm_get_gdb_reg_list(struct target *target, for (i = 13; i < ARRAY_SIZE(arm_core_regs); i++) { int reg_index = arm->core_cache->reg_list[i].number; - if (!(arm_core_regs[i].mode == ARM_MODE_MON - && arm->core_type != ARM_CORE_TYPE_SEC_EXT)) - (*reg_list)[reg_index] = &(arm->core_cache->reg_list[i]); + + if (arm_core_regs[i].mode == ARM_MODE_MON + && arm->core_type != ARM_CORE_TYPE_SEC_EXT + && arm->core_type != ARM_CORE_TYPE_VIRT_EXT) + continue; + if (arm_core_regs[i].mode == ARM_MODE_HYP + && arm->core_type != ARM_CORE_TYPE_VIRT_EXT) + continue; + (*reg_list)[reg_index] = &(arm->core_cache->reg_list[i]); } /* When we supply the target description, there is no need for fake FPA */ diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h index 3ce4ed0e5..bef1cfe32 100644 --- a/src/target/armv4_5.h +++ b/src/target/armv4_5.h @@ -38,7 +38,7 @@ int arm_mode_to_number(enum arm_mode mode); enum arm_mode armv4_5_number_to_mode(int number); -extern const int armv4_5_core_reg_map[8][17]; +extern const int armv4_5_core_reg_map[9][17]; #define ARMV4_5_CORE_REG_MODE(cache, mode, num) \ (cache->reg_list[armv4_5_core_reg_map[arm_mode_to_number(mode)][num]]) diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 22cbc3d06..729a173eb 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -2797,6 +2797,15 @@ static int cortex_a_examine_first(struct target *target) target->coreid); armv7a->arm.core_type = ARM_CORE_TYPE_SEC_EXT; } + if (dbg_idpfr1 & 0x0000f000) { + LOG_DEBUG("target->coreid %" PRId32 " has virtualization extensions", + target->coreid); + /* + * overwrite and simplify the checks. + * virtualization extensions require implementation of security extension + */ + armv7a->arm.core_type = ARM_CORE_TYPE_VIRT_EXT; + } /* Avoid recreating the registers cache */ if (!target_was_examined(target)) { From a34c336cbf7dbe3540cbce59a9b10e81c28fa32a Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Fri, 6 Mar 2020 14:39:14 -0600 Subject: [PATCH 197/354] drivers: xds110: Fix errors in routine that toggles TCK during nSRST assert/deassert code. To support LPRF targets (CC13xx/CC26xx), TCK must be toggled for 50 ms while nSRST is asserted and right after it is released. This allows the core to halt in boot ROM before code is run that might interfere with debug access. The current routine has two issues. It shouldn't be run at all if the target is using SWD. And the delay needs to be a real-time 50 ms, so the number of TCK periods should be calculated off the set speed. Change-Id: If993031b84cf2a505ea67a6633602c4b01cd8e1e Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5497 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/drivers/xds110.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index 14bfe9c75..69d989520 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -1624,7 +1624,11 @@ static int xds110_reset(int trst, int srst) retval = ERROR_FAIL; /* Toggle TCK to trigger HIB on CC13x/CC26x devices */ - success = xds_cycle_tck(60000); + if (success && !xds110.is_swd_mode) { + /* Toggle TCK for about 50 ms */ + success = xds_cycle_tck(xds110.speed * 50); + } + if (!success) retval = ERROR_FAIL; } From e03de33c412b366f3dd45c447410dcc1df3b4b82 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 8 Feb 2020 07:02:28 +0100 Subject: [PATCH 198/354] tcl/target: Fix naming of RZ/A1 SoC The RZ/A1 is not part of the R-Car family, but is rather an RZ family. Fix the naming. Change-Id: I5f882b2467e87e534e0f1c827554e664a7d55664 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5445 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/target/renesas_r7s72100.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcl/target/renesas_r7s72100.cfg b/tcl/target/renesas_r7s72100.cfg index f9466fc2f..5220b3ccb 100644 --- a/tcl/target/renesas_r7s72100.cfg +++ b/tcl/target/renesas_r7s72100.cfg @@ -1,4 +1,4 @@ -# Renesas R-Car RZ/A1H +# Renesas RZ/A1H # https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/rz/rza/rza1h.html if { [info exists DAP_TAPID] } { From ba131f30a0798d97729f9517c136d32f58f57571 Mon Sep 17 00:00:00 2001 From: Andreas Bolsch Date: Sun, 16 Dec 2018 17:30:41 +0100 Subject: [PATCH 199/354] Flash driver for STM32G0xx and STM32G4xx Flash module of STM32G0/G4 family is quite similar to the one of STM32L4, so only minor changes are required, in particular adaption of flash loader to Cortex-M0. Register addresses passed to flash loader to simplify integration of L5. Added re-probe after option byte load. Added flash size override via cfg file. WRPxxR mask now based on max. number of pages instead of fixed 0xFF, as G4 devices fill up unused bits with '1'. Sizes in stm32l4_probe changed to multiples of 1kB. Tested with Nucleo-G071RB, G030J6, Nucleo-G431RB and Nucleo-G474RE. Gap handling in G4 Cat. 3 dual bank mode tested with STM32G473RB. This handling isn't optimal as the bank size includes the size of the gap. WB not tested. Change-Id: I24df7c065afeb71c11c7e96de4aa9fdb91845593 Signed-off-by: Andreas Bolsch Reviewed-on: http://openocd.zylin.com/4807 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Tomas Vanek --- contrib/loaders/flash/stm32/stm32l4x.S | 96 ++--- contrib/loaders/flash/stm32/stm32l4x.inc | 12 +- doc/openocd.texi | 11 +- src/flash/nor/Makefile.am | 1 + src/flash/nor/stm32l4x.c | 443 +++++++++++++++-------- src/flash/nor/stm32l4x.h | 82 +++++ tcl/target/stm32g0x.cfg | 88 +++++ tcl/target/stm32g4x.cfg | 103 ++++++ 8 files changed, 641 insertions(+), 195 deletions(-) create mode 100644 src/flash/nor/stm32l4x.h create mode 100644 tcl/target/stm32g0x.cfg create mode 100644 tcl/target/stm32g4x.cfg diff --git a/contrib/loaders/flash/stm32/stm32l4x.S b/contrib/loaders/flash/stm32/stm32l4x.S index e0ce3cb34..9e5c41eba 100644 --- a/contrib/loaders/flash/stm32/stm32l4x.S +++ b/contrib/loaders/flash/stm32/stm32l4x.S @@ -8,6 +8,9 @@ * Copyright (C) 2015 Uwe Bonnes * * bon@elektron.ikp.physik.tu-darmstadt.de * * * + * Copyright (C) 2018 Andreas Bolsch * + * andreas.bolsch@mni.thm.de * + * * * 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 * * the Free Software Foundation; either version 2 of the License, or * @@ -25,68 +28,79 @@ .text .syntax unified - .cpu cortex-m4 + .cpu cortex-m0 .thumb /* * Params : * r0 = workarea start, status (out) - * r1 = workarea end + * r1 = workarea end + 1 * r2 = target address * r3 = count (64bit words) - * r4 = flash base + * r4 = flash status register + * r5 = flash control register * * Clobbered: - * r5 - rp * r6/7 - temp (64-bit) - * r8 - wp, tmp */ -#define STM32_FLASH_CR_OFFSET 0x14 /* offset of CR register in FLASH struct */ -#define STM32_FLASH_SR_OFFSET 0x10 /* offset of SR register in FLASH struct */ - -#define STM32_PROG 0x1 /* PG */ +#include "../../../../src/flash/nor/stm32l4x.h" .thumb_func .global _start + _start: + mov r8, r3 /* copy dword count */ wait_fifo: - ldr r8, [r0, #0] /* read wp */ - cmp r8, #0 /* abort if wp == 0 */ - beq exit - ldr r5, [r0, #4] /* read rp */ - subs r6, r8, r5 /* number of bytes available for read in r6*/ - itt mi /* if wrapped around*/ - addmi r6, r1 /* add size of buffer */ - submi r6, r0 - cmp r6, #8 /* wait until 8 bytes are available */ - bcc wait_fifo + ldr r6, [r0, #0] /* read wp */ + cmp r6, #0 /* if wp == 0, */ + beq exit /* then abort */ + ldr r3, [r0, #4] /* read rp */ + subs r6, r6, r3 /* number of bytes available for read in r6 */ + bpl fifo_stat /* if not wrapped around, skip */ + adds r6, r6, r1 /* add end of buffer */ + subs r6, r6, r0 /* sub start of buffer */ +fifo_stat: + cmp r6, #8 /* wait until at least one dword available */ + bcc wait_fifo - ldr r6, =STM32_PROG - str r6, [r4, #STM32_FLASH_CR_OFFSET] - ldrd r6, [r5], #0x08 /* read one word from src, increment ptr */ - strd r6, [r2], #0x08 /* write one word to dst, increment ptr */ + movs r6, #FLASH_PG /* flash program enable */ + str r6, [r5] /* write to FLASH_CR, start operation */ + ldmia r3!, {r6, r7} /* read one dword from src, increment ptr */ + stmia r2!, {r6, r7} /* write one dword to dst, increment ptr */ dsb + ldr r7, =FLASH_BSY /* FLASH_BSY mask */ busy: - ldr r6, [r4, #STM32_FLASH_SR_OFFSET] - tst r6, #0x10000 /* BSY (bit16) == 1 => operation in progress */ - bne busy /* wait more... */ - tst r6, #0xfa /* PGSERR | SIZERR | PGAERR | WRPERR | PROGERR | OPERR */ - bne error /* fail... */ + ldr r6, [r4] /* get FLASH_SR register */ + tst r6, r7 /* BSY == 1 => operation in progress */ + bne busy /* if still set, wait more ... */ + movs r7, #FLASH_ERROR /* all error bits */ + tst r6, r7 /* check for any error bit */ + bne error /* fail ... */ - cmp r5, r1 /* wrap rp at end of buffer */ - it cs - addcs r5, r0, #8 /* skip loader args */ - str r5, [r0, #4] /* store rp */ - subs r3, r3, #1 /* decrement dword count */ - cbz r3, exit /* loop if not done */ - b wait_fifo -error: - movs r1, #0 - str r1, [r0, #4] /* set rp = 0 on error */ -exit: - mov r0, r6 /* return status in r0 */ - bkpt #0x00 + cmp r3, r1 /* rp at end of buffer? */ + bcc upd_rp /* if no, then skip */ + subs r3, r3, r1 /* sub end of buffer */ + adds r3, r3, r0 /* add start of buffer */ + adds r3, r3, #8 /* skip wp and rp */ +upd_rp: + str r3, [r0, #4] /* store rp */ + mov r7, r8 /* get dword count */ + subs r7, r7, #1 /* decrement dword count */ + mov r8, r7 /* save dword count */ + beq exit /* exit if done */ + b wait_fifo .pool +error: + movs r3, #0 + str r3, [r0, #4] /* set rp = 0 on error */ +exit: + mov r0, r6 /* return status in r0 */ + movs r6, #0 /* flash program disable */ + str r6, [r5] /* write to FLASH_CR */ + movs r6, #FLASH_ERROR /* all error bits */ + str r6, [r4] /* write to FLASH_CR to clear errors */ + bkpt #0x00 + diff --git a/contrib/loaders/flash/stm32/stm32l4x.inc b/contrib/loaders/flash/stm32/stm32l4x.inc index 4065d14ef..df5c7edd1 100644 --- a/contrib/loaders/flash/stm32/stm32l4x.inc +++ b/contrib/loaders/flash/stm32/stm32l4x.inc @@ -1,7 +1,7 @@ /* Autogenerated with ../../../../src/helper/bin2char.sh */ -0xd0,0xf8,0x00,0x80,0xb8,0xf1,0x00,0x0f,0x20,0xd0,0x45,0x68,0xb8,0xeb,0x05,0x06, -0x44,0xbf,0x76,0x18,0x36,0x1a,0x08,0x2e,0xf2,0xd3,0x0d,0x4e,0x66,0x61,0xf5,0xe8, -0x02,0x67,0xe2,0xe8,0x02,0x67,0xbf,0xf3,0x4f,0x8f,0x26,0x69,0x16,0xf4,0x80,0x3f, -0xfb,0xd1,0x16,0xf0,0xfa,0x0f,0x07,0xd1,0x8d,0x42,0x28,0xbf,0x00,0xf1,0x08,0x05, -0x45,0x60,0x01,0x3b,0x13,0xb1,0xdb,0xe7,0x00,0x21,0x41,0x60,0x30,0x46,0x00,0xbe, -0x01,0x00,0x00,0x00, +0x98,0x46,0x06,0x68,0x00,0x2e,0x23,0xd0,0x43,0x68,0xf6,0x1a,0x01,0xd5,0x76,0x18, +0x36,0x1a,0x08,0x2e,0xf5,0xd3,0x01,0x26,0x2e,0x60,0xc0,0xcb,0xc0,0xc2,0xbf,0xf3, +0x4f,0x8f,0x09,0x4f,0x26,0x68,0x3e,0x42,0xfc,0xd1,0xfa,0x27,0x3e,0x42,0x0d,0xd1, +0x8b,0x42,0x02,0xd3,0x5b,0x1a,0x1b,0x18,0x08,0x33,0x43,0x60,0x47,0x46,0x01,0x3f, +0xb8,0x46,0x05,0xd0,0xdd,0xe7,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x23,0x43,0x60, +0x30,0x46,0x00,0x26,0x2e,0x60,0xfa,0x26,0x26,0x60,0x00,0xbe, diff --git a/doc/openocd.texi b/doc/openocd.texi index 711171a34..97c5a728d 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6892,8 +6892,10 @@ The @var{num} parameter is a value shown by @command{flash banks}. @end deffn @deffn {Flash Driver} stm32l4x -All members of the STM32L4 and STM32WB microcontroller families from STMicroelectronics -include internal flash and use ARM Cortex-M4 cores. +All members of the STM32L4, STM32L4+, STM32WB and STM32G4 +microcontroller families from STMicroelectronics include internal flash +and use ARM Cortex-M4 cores. +Additionally this driver supports STM32G0 family with ARM Cortex-M0+ core. The driver automatically recognizes a number of these chips using the chip identification register, and autoconfigures itself. @@ -6903,7 +6905,8 @@ flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME Note that some devices have been found that have a flash size register that contains an invalid value, to workaround this issue you can override the probed value used by -the flash driver. +the flash driver. However, specifying a wrong value might lead to a completely +wrong flash layout, so this feature must be used carefully. @example flash bank $_FLASHNAME stm32l4x 0x08000000 0x40000 0 0 $_TARGETNAME @@ -6960,7 +6963,7 @@ This will effectively write protect all sectors in flash bank 1. @end deffn @deffn Command {stm32l4x option_load} num -Forces a re-load of the option byte registers. Will cause a reset of the device. +Forces a re-load of the option byte registers. Will cause a system reset of the device. The @var{num} parameter is a value shown by @command{flash banks}. @end deffn @end deffn diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index 64c4a9079..b95b003df 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -84,4 +84,5 @@ NORHEADERS = \ %D%/non_cfi.h \ %D%/ocl.h \ %D%/spi.h \ + %D%/stm32l4x.h \ %D%/msp432.h diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index abbb75b46..b6f0d714d 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -28,6 +28,7 @@ #include #include #include "bits.h" +#include "stm32l4x.h" /* STM32L4xxx series for reference. * @@ -65,66 +66,44 @@ * */ +/* STM32WBxxx series for reference. + * + * RM0434 (STM32WB55) + * http://www.st.com/resource/en/reference_manual/dm00318631.pdf + * + * RM0471 (STM32WB50) + * http://www.st.com/resource/en/reference_manual/dm00622834.pdf + */ + +/* + * STM32G0xxx series for reference. + * + * RM0444 (STM32G0x1) + * http://www.st.com/resource/en/reference_manual/dm00371828.pdf + * + * RM0454 (STM32G0x0) + * http://www.st.com/resource/en/reference_manual/dm00463896.pdf + */ + +/* + * STM32G4xxx series for reference. + * + * RM0440 (STM32G43x/44x/47x/48x) + * http://www.st.com/resource/en/reference_manual/dm00355726.pdf + * + * Cat. 2 devices have single bank only, page size is 2kByte. + * + * Cat. 3 devices have single and dual bank operating modes, + * Page size is 2kByte (dual mode) or 4kByte (single mode). + * + * Bank mode is controlled by bit 22 (DBANK) in option bytes register. + * Both banks are treated as a single OpenOCD bank. + */ + /* Erase time can be as high as 25ms, 10x this and assume it's toast... */ #define FLASH_ERASE_TIMEOUT 250 -/* Flash registers offsets */ -#define STM32_FLASH_ACR 0x00 -#define STM32_FLASH_KEYR 0x08 -#define STM32_FLASH_OPTKEYR 0x0c -#define STM32_FLASH_SR 0x10 -#define STM32_FLASH_CR 0x14 -#define STM32_FLASH_OPTR 0x20 -#define STM32_FLASH_WRP1AR 0x2c -#define STM32_FLASH_WRP1BR 0x30 -#define STM32_FLASH_WRP2AR 0x4c -#define STM32_FLASH_WRP2BR 0x50 - -/* FLASH_CR register bits */ -#define FLASH_PG (1 << 0) -#define FLASH_PER (1 << 1) -#define FLASH_MER1 (1 << 2) -#define FLASH_PAGE_SHIFT 3 -#define FLASH_CR_BKER (1 << 11) -#define FLASH_MER2 (1 << 15) -#define FLASH_STRT (1 << 16) -#define FLASH_OPTSTRT (1 << 17) -#define FLASH_EOPIE (1 << 24) -#define FLASH_ERRIE (1 << 25) -#define FLASH_OBLLAUNCH (1 << 27) -#define FLASH_OPTLOCK (1 << 30) -#define FLASH_LOCK (1 << 31) - -/* FLASH_SR register bits */ -#define FLASH_BSY (1 << 16) -/* Fast programming not used => related errors not used*/ -#define FLASH_PGSERR (1 << 7) /* Programming sequence error */ -#define FLASH_SIZERR (1 << 6) /* Size error */ -#define FLASH_PGAERR (1 << 5) /* Programming alignment error */ -#define FLASH_WRPERR (1 << 4) /* Write protection error */ -#define FLASH_PROGERR (1 << 3) /* Programming error */ -#define FLASH_OPERR (1 << 1) /* Operation error */ -#define FLASH_EOP (1 << 0) /* End of operation */ -#define FLASH_ERROR (FLASH_PGSERR | FLASH_SIZERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_PROGERR | FLASH_OPERR) - -/* register unlock keys */ -#define KEY1 0x45670123 -#define KEY2 0xCDEF89AB - -/* option register unlock key */ -#define OPTKEY1 0x08192A3B -#define OPTKEY2 0x4C5D6E7F - -#define RDP_LEVEL_0 0xAA -#define RDP_LEVEL_1 0xBB -#define RDP_LEVEL_2 0xCC - - -/* other registers */ -#define DBGMCU_IDCODE 0xE0042000 - - struct stm32l4_rev { const uint16_t rev; const char *str; @@ -147,9 +126,14 @@ struct stm32l4_flash_bank { int bank1_sectors; bool dual_bank_mode; int hole_sectors; + uint32_t user_bank_size; + uint32_t wrpxxr_mask; const struct stm32l4_part_info *part_info; }; +/* human readable list of families this drivers supports */ +static const char *device_families = "STM32L4/L4+/WB/G4/G0"; + static const struct stm32l4_rev stm32_415_revs[] = { { 0x1000, "1" }, { 0x1001, "2" }, { 0x1003, "3" }, { 0x1007, "4" } }; @@ -158,16 +142,32 @@ static const struct stm32l4_rev stm32_435_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" }, }; +static const struct stm32l4_rev stm32_460_revs[] = { + { 0x1000, "A/Z" } /* A and Z, no typo in RM! */, { 0x2000, "B" }, +}; + static const struct stm32l4_rev stm32_461_revs[] = { { 0x1000, "A" }, { 0x2000, "B" }, }; static const struct stm32l4_rev stm32_462_revs[] = { - { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" }, + { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" }, }; static const struct stm32l4_rev stm32_464_revs[] = { - { 0x1000, "A" }, + { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2001, "Y" }, +}; + +static const struct stm32l4_rev stm32_466_revs[] = { + { 0x1000, "A" }, { 0x1001, "Z" }, { 0x2000, "B" }, +}; + +static const struct stm32l4_rev stm32_468_revs[] = { + { 0x1000, "A" }, { 0x2000, "B" }, { 0x2001, "Z" }, +}; + +static const struct stm32l4_rev stm32_469_revs[] = { + { 0x1000, "A" }, { 0x2000, "B" }, { 0x2001, "Z" }, }; static const struct stm32l4_rev stm32_470_revs[] = { @@ -203,6 +203,16 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .flash_regs_base = 0x40022000, .fsize_addr = 0x1FFF75E0, }, + { + .id = 0x460, + .revs = stm32_460_revs, + .num_revs = ARRAY_SIZE(stm32_460_revs), + .device_str = "STM32G07/G08xx", + .max_flash_size_kb = 128, + .has_dual_bank = false, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, { .id = 0x461, .revs = stm32_461_revs, @@ -233,6 +243,36 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .flash_regs_base = 0x40022000, .fsize_addr = 0x1FFF75E0, }, + { + .id = 0x466, + .revs = stm32_466_revs, + .num_revs = ARRAY_SIZE(stm32_466_revs), + .device_str = "STM32G03/G04xx", + .max_flash_size_kb = 64, + .has_dual_bank = false, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, + { + .id = 0x468, + .revs = stm32_468_revs, + .num_revs = ARRAY_SIZE(stm32_468_revs), + .device_str = "STM32G43/G44xx", + .max_flash_size_kb = 128, + .has_dual_bank = false, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, + { + .id = 0x469, + .revs = stm32_469_revs, + .num_revs = ARRAY_SIZE(stm32_469_revs), + .device_str = "STM32G47/G48xx", + .max_flash_size_kb = 512, + .has_dual_bank = true, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75E0, + }, { .id = 0x470, .revs = stm32_470_revs, @@ -283,6 +323,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command) bank->write_start_alignment = bank->write_end_alignment = 8; stm32l4_info->probed = false; + stm32l4_info->user_bank_size = bank->size; return ERROR_OK; } @@ -409,7 +450,8 @@ static int stm32l4_unlock_option_reg(struct flash_bank *bank) return ERROR_OK; } -static int stm32l4_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value, uint32_t mask) +static int stm32l4_write_option(struct flash_bank *bank, uint32_t reg_offset, + uint32_t value, uint32_t mask) { uint32_t optiondata; int retval, retval2; @@ -454,17 +496,23 @@ static int stm32l4_protect_check(struct flash_bank *bank) uint32_t wrp1ar, wrp1br, wrp2ar, wrp2br; stm32l4_read_flash_reg(bank, STM32_FLASH_WRP1AR, &wrp1ar); stm32l4_read_flash_reg(bank, STM32_FLASH_WRP1BR, &wrp1br); - stm32l4_read_flash_reg(bank, STM32_FLASH_WRP2AR, &wrp2ar); - stm32l4_read_flash_reg(bank, STM32_FLASH_WRP2BR, &wrp2br); + if (stm32l4_info->part_info->has_dual_bank) { + stm32l4_read_flash_reg(bank, STM32_FLASH_WRP2AR, &wrp2ar); + stm32l4_read_flash_reg(bank, STM32_FLASH_WRP2BR, &wrp2br); + } else { + /* prevent unintialized errors */ + wrp2ar = 0; + wrp2br = 0; + } - const uint8_t wrp1a_start = wrp1ar & 0xFF; - const uint8_t wrp1a_end = (wrp1ar >> 16) & 0xFF; - const uint8_t wrp1b_start = wrp1br & 0xFF; - const uint8_t wrp1b_end = (wrp1br >> 16) & 0xFF; - const uint8_t wrp2a_start = wrp2ar & 0xFF; - const uint8_t wrp2a_end = (wrp2ar >> 16) & 0xFF; - const uint8_t wrp2b_start = wrp2br & 0xFF; - const uint8_t wrp2b_end = (wrp2br >> 16) & 0xFF; + const uint8_t wrp1a_start = wrp1ar & stm32l4_info->wrpxxr_mask; + const uint8_t wrp1a_end = (wrp1ar >> 16) & stm32l4_info->wrpxxr_mask; + const uint8_t wrp1b_start = wrp1br & stm32l4_info->wrpxxr_mask; + const uint8_t wrp1b_end = (wrp1br >> 16) & stm32l4_info->wrpxxr_mask; + const uint8_t wrp2a_start = wrp2ar & stm32l4_info->wrpxxr_mask; + const uint8_t wrp2a_end = (wrp2ar >> 16) & stm32l4_info->wrpxxr_mask; + const uint8_t wrp2b_start = wrp2br & stm32l4_info->wrpxxr_mask; + const uint8_t wrp2b_end = (wrp2br >> 16) & stm32l4_info->wrpxxr_mask; for (int i = 0; i < bank->num_sectors; i++) { if (i < stm32l4_info->bank1_sectors) { @@ -476,6 +524,7 @@ static int stm32l4_protect_check(struct flash_bank *bank) else bank->sectors[i].is_protected = 0; } else { + assert(stm32l4_info->part_info->has_dual_bank == true); uint8_t snb; snb = i - stm32l4_info->bank1_sectors; if (((snb >= wrp2a_start) && @@ -496,8 +545,7 @@ static int stm32l4_erase(struct flash_bank *bank, int first, int last) int i; int retval, retval2; - assert(first < bank->num_sectors); - assert(last < bank->num_sectors); + assert((0 <= first) && (first <= last) && (last < bank->num_sectors)); if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -512,7 +560,7 @@ static int stm32l4_erase(struct flash_bank *bank, int first, int last) Sector Erase To erase a sector, follow the procedure below: 1. Check that no Flash memory operation is ongoing by - checking the BSY bit in the FLASH_SR register + checking the BSY bit in the FLASH_SR register 2. Set the PER bit and select the page and bank you wish to erase in the FLASH_CR register 3. Set the STRT bit in the FLASH_CR register @@ -586,15 +634,15 @@ static int stm32l4_protect(struct flash_bank *bank, int set, int first, int last /* Count is in double-words */ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) + uint32_t offset, uint32_t count) { struct target *target = bank->target; struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; - uint32_t buffer_size = 16384; + uint32_t buffer_size; struct working_area *write_algorithm; struct working_area *source; uint32_t address = bank->base + offset; - struct reg_param reg_params[5]; + struct reg_param reg_params[6]; struct armv7m_algorithm armv7m_info; int retval = ERROR_OK; @@ -616,18 +664,19 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, return retval; } - /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != - ERROR_OK) { - buffer_size /= 2; - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); + /* memory buffer, size *must* be multiple of dword plus one dword for rp and one for wp */ + buffer_size = target_get_working_area_avail(target) & ~(2 * sizeof(uint32_t) - 1); + if (buffer_size < 256) { + LOG_WARNING("large enough working area not available, can't do block memory writes"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } else if (buffer_size > 16384) { + /* probably won't benefit from more than 16k ... */ + buffer_size = 16384; + } - LOG_WARNING("large enough working area not available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + if (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { + LOG_ERROR("allocating working area failed"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; @@ -637,17 +686,19 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */ init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */ init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (double word-64bit) */ - init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* flash regs base */ + init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* flash status register */ + init_reg_param(®_params[5], "r5", 32, PARAM_OUT); /* flash control register */ buf_set_u32(reg_params[0].value, 0, 32, source->address); buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); buf_set_u32(reg_params[2].value, 0, 32, address); buf_set_u32(reg_params[3].value, 0, 32, count); - buf_set_u32(reg_params[4].value, 0, 32, stm32l4_info->part_info->flash_regs_base); + buf_set_u32(reg_params[4].value, 0, 32, stm32l4_info->part_info->flash_regs_base + STM32_FLASH_SR); + buf_set_u32(reg_params[5].value, 0, 32, stm32l4_info->part_info->flash_regs_base + STM32_FLASH_CR); retval = target_run_flash_async_algorithm(target, buffer, count, 8, 0, NULL, - 5, reg_params, + ARRAY_SIZE(reg_params), reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info); @@ -676,14 +727,15 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, destroy_reg_param(®_params[2]); destroy_reg_param(®_params[3]); destroy_reg_param(®_params[4]); + destroy_reg_param(®_params[5]); return retval; } static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, - uint32_t offset, uint32_t count) + uint32_t offset, uint32_t count) { - int retval, retval2; + int retval = ERROR_OK, retval2; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -695,6 +747,43 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, assert(offset % 8 == 0); assert(count % 8 == 0); + /* STM32G4xxx Cat. 3 devices may have gaps between banks, check whether + * data to be written does not go into a gap: + * suppose buffer is fully contained in bank from sector 0 to sector + * num->sectors - 1 and sectors are ordered according to offset + */ + struct flash_sector *head = &bank->sectors[0]; + struct flash_sector *tail = &bank->sectors[bank->num_sectors - 1]; + + while ((head < tail) && (offset >= (head + 1)->offset)) { + /* buffer does not intersect head nor gap behind head */ + head++; + } + + while ((head < tail) && (offset + count <= (tail - 1)->offset + (tail - 1)->size)) { + /* buffer does not intersect tail nor gap before tail */ + --tail; + } + + LOG_DEBUG("data: 0x%08" PRIx32 " - 0x%08" PRIx32 ", sectors: 0x%08" PRIx32 " - 0x%08" PRIx32, + offset, offset + count - 1, head->offset, tail->offset + tail->size - 1); + + /* Now check that there is no gap from head to tail, this should work + * even for multiple or non-symmetric gaps + */ + while (head < tail) { + if (head->offset + head->size != (head + 1)->offset) { + LOG_ERROR("write into gap from " TARGET_ADDR_FMT " to " TARGET_ADDR_FMT, + bank->base + head->offset + head->size, + bank->base + (head + 1)->offset - 1); + retval = ERROR_FLASH_DST_OUT_OF_BANK; + } + head++; + } + + if (retval != ERROR_OK) + return retval; + retval = stm32l4_unlock_reg(bank); if (retval != ERROR_OK) goto err_lock; @@ -713,9 +802,17 @@ err_lock: static int stm32l4_read_idcode(struct flash_bank *bank, uint32_t *id) { - int retval = target_read_u32(bank->target, DBGMCU_IDCODE, id); - if (retval != ERROR_OK) - return retval; + int retval; + + /* try stm32l4/l4+/wb/g4 id register first, then stm32g0 id register */ + retval = target_read_u32(bank->target, DBGMCU_IDCODE_L4_G4, id); + if ((retval != ERROR_OK) || ((*id & 0xfff) == 0) || ((*id & 0xfff) == 0xfff)) { + retval = target_read_u32(bank->target, DBGMCU_IDCODE_G0, id); + if ((retval != ERROR_OK) || ((*id & 0xfff) == 0) || ((*id & 0xfff) == 0xfff)) { + LOG_ERROR("can't get device id"); + return (retval == ERROR_OK) ? ERROR_FAIL : retval; + } + } return retval; } @@ -725,13 +822,13 @@ static int stm32l4_probe(struct flash_bank *bank) struct target *target = bank->target; struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; const struct stm32l4_part_info *part_info; - uint16_t flash_size_in_kb = 0xffff; + uint16_t flash_size_kb = 0xffff; uint32_t device_id; uint32_t options; stm32l4_info->probed = false; - /* read stm32 device id register */ + /* read stm32 device id registers */ int retval = stm32l4_read_idcode(bank, &stm32l4_info->idcode); if (retval != ERROR_OK) return retval; @@ -744,7 +841,7 @@ static int stm32l4_probe(struct flash_bank *bank) } if (!stm32l4_info->part_info) { - LOG_WARNING("Cannot identify target as an STM32 L4 or WB family device."); + LOG_WARNING("Cannot identify target as an %s family device.", device_families); return ERROR_FAIL; } @@ -758,21 +855,28 @@ static int stm32l4_probe(struct flash_bank *bank) LOG_INFO("device idcode = 0x%08" PRIx32 " (%s)", stm32l4_info->idcode, device_info); /* get flash size from target. */ - retval = target_read_u16(target, part_info->fsize_addr, &flash_size_in_kb); + retval = target_read_u16(target, part_info->fsize_addr, &flash_size_kb); /* failed reading flash size or flash size invalid (early silicon), * default to max target family */ - if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0 - || flash_size_in_kb > part_info->max_flash_size_kb) { + if (retval != ERROR_OK || flash_size_kb == 0xffff || flash_size_kb == 0 + || flash_size_kb > part_info->max_flash_size_kb) { LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming %dk flash", part_info->max_flash_size_kb); - flash_size_in_kb = part_info->max_flash_size_kb; + flash_size_kb = part_info->max_flash_size_kb; } - LOG_INFO("flash size = %dkbytes", flash_size_in_kb); + /* if the user sets the size manually then ignore the probed value + * this allows us to work around devices that have a invalid flash size register value */ + if (stm32l4_info->user_bank_size) { + LOG_WARNING("overriding size register by configured bank size - MAY CAUSE TROUBLE"); + flash_size_kb = stm32l4_info->user_bank_size / 1024; + } + + LOG_INFO("flash size = %dkbytes", flash_size_kb); /* did we assign a flash size? */ - assert((flash_size_in_kb != 0xffff) && flash_size_in_kb); + assert((flash_size_kb != 0xffff) && flash_size_kb); /* read flash option register */ retval = stm32l4_read_flash_reg(bank, STM32_FLASH_OPTR, &options); @@ -783,13 +887,13 @@ static int stm32l4_probe(struct flash_bank *bank) stm32l4_info->hole_sectors = 0; int num_pages = 0; - int page_size = 0; + int page_size_kb = 0; stm32l4_info->dual_bank_mode = false; switch (device_id) { - case 0x415: - case 0x461: + case 0x415: /* STM32L47/L48xx */ + case 0x461: /* STM32L49/L4Axx */ /* if flash size is max (1M) the device is always dual bank * 0x415: has variants with 512K * 0x461: has variants with 512 and 256 @@ -798,51 +902,71 @@ static int stm32l4_probe(struct flash_bank *bank) * else -> dual bank without gap * note: the page size is invariant */ - page_size = 2048; - num_pages = flash_size_in_kb / 2; + page_size_kb = 2; + num_pages = flash_size_kb / page_size_kb; stm32l4_info->bank1_sectors = num_pages; /* check DUAL_BANK bit[21] if the flash is less than 1M */ - if (flash_size_in_kb == 1024 || (options & BIT(21))) { + if (flash_size_kb == 1024 || (options & BIT(21))) { stm32l4_info->dual_bank_mode = true; stm32l4_info->bank1_sectors = num_pages / 2; } break; - case 0x435: - case 0x462: - case 0x464: + case 0x435: /* STM32L43/L44xx */ + case 0x460: /* STM32G07/G08xx */ + case 0x462: /* STM32L45/L46xx */ + case 0x464: /* STM32L41/L42xx */ + case 0x466: /* STM32G03/G04xx */ + case 0x468: /* STM32G43/G44xx */ /* single bank flash */ - page_size = 2048; - num_pages = flash_size_in_kb / 2; + page_size_kb = 2; + num_pages = flash_size_kb / page_size_kb; stm32l4_info->bank1_sectors = num_pages; break; - case 0x470: - case 0x471: + case 0x469: /* STM32G47/G48xx */ + /* STM32G47/8 can be single/dual bank: + * if DUAL_BANK = 0 -> single bank + * else -> dual bank WITH gap + */ + page_size_kb = 4; + num_pages = flash_size_kb / page_size_kb; + stm32l4_info->bank1_sectors = num_pages; + if (options & BIT(22)) { + stm32l4_info->dual_bank_mode = true; + page_size_kb = 2; + num_pages = flash_size_kb / page_size_kb; + stm32l4_info->bank1_sectors = num_pages / 2; + + /* for devices with trimmed flash, there is a gap between both banks */ + stm32l4_info->hole_sectors = + (part_info->max_flash_size_kb - flash_size_kb) / (2 * page_size_kb); + } + break; + case 0x470: /* STM32L4R/L4Sxx */ + case 0x471: /* STM32L4P5/L4Q5x */ /* STM32L4R/S can be single/dual bank: * if size = 2M check DBANK bit(22) * if size = 1M check DB1M bit(21) * STM32L4P/Q can be single/dual bank * if size = 1M check DBANK bit(22) * if size = 512K check DB512K bit(21) - * in single bank configuration the page size is 8K - * else (dual bank) the page size is 4K without gap between banks */ - page_size = 8192; - num_pages = flash_size_in_kb / 8; + page_size_kb = 8; + num_pages = flash_size_kb / page_size_kb; stm32l4_info->bank1_sectors = num_pages; - const bool use_dbank_bit = flash_size_in_kb == part_info->max_flash_size_kb; + const bool use_dbank_bit = flash_size_kb == part_info->max_flash_size_kb; if ((use_dbank_bit && (options & BIT(22))) || (!use_dbank_bit && (options & BIT(21)))) { stm32l4_info->dual_bank_mode = true; - page_size = 4096; - num_pages = flash_size_in_kb / 4; + page_size_kb = 4; + num_pages = flash_size_kb / page_size_kb; stm32l4_info->bank1_sectors = num_pages / 2; } break; - case 0x495: + case 0x495: /* STM32WB5x */ /* single bank flash */ - page_size = 4096; - num_pages = flash_size_in_kb / 4; + page_size_kb = 4; + num_pages = flash_size_kb / page_size_kb; stm32l4_info->bank1_sectors = num_pages; break; default: @@ -852,21 +976,41 @@ static int stm32l4_probe(struct flash_bank *bank) LOG_INFO("flash mode : %s-bank", stm32l4_info->dual_bank_mode ? "dual" : "single"); - const int gap_size = stm32l4_info->hole_sectors * page_size; + const int gap_size_kb = stm32l4_info->hole_sectors * page_size_kb; - if (stm32l4_info->dual_bank_mode & gap_size) { - LOG_INFO("gap detected starting from %0x08" PRIx32 " to %0x08" PRIx32, - 0x8000000 + stm32l4_info->bank1_sectors * page_size, - 0x8000000 + stm32l4_info->bank1_sectors * page_size + gap_size); + if (gap_size_kb != 0) { + LOG_INFO("gap detected from 0x%08" PRIx32 " to 0x%08" PRIx32, + STM32_FLASH_BANK_BASE + stm32l4_info->bank1_sectors + * page_size_kb * 1024, + STM32_FLASH_BANK_BASE + (stm32l4_info->bank1_sectors + * page_size_kb + gap_size_kb) * 1024 - 1); } + /* number of significant bits in WRPxxR differs per device, + * always right adjusted, on some devices non-implemented + * bits read as '0', on others as '1' ... + * notably G4 Cat. 2 implement only 6 bits, contradicting the RM + */ + + /* use *max_flash_size* instead of actual size as the trimmed versions + * certainly use the same number of bits + * max_flash_size is always power of two, so max_pages too + */ + uint32_t max_pages = stm32l4_info->part_info->max_flash_size_kb / page_size_kb; + assert((max_pages & (max_pages - 1)) == 0); + + /* in dual bank mode number of pages is doubled, but extra bit is bank selection */ + stm32l4_info->wrpxxr_mask = ((max_pages >> (stm32l4_info->dual_bank_mode ? 1 : 0)) - 1); + assert((stm32l4_info->wrpxxr_mask & 0xFFFF0000) == 0); + LOG_DEBUG("WRPxxR mask 0x%04" PRIx16, stm32l4_info->wrpxxr_mask); + if (bank->sectors) { free(bank->sectors); bank->sectors = NULL; } - bank->size = flash_size_in_kb * 1024 + gap_size; - bank->base = 0x08000000; + bank->size = (flash_size_kb + gap_size_kb) * 1024; + bank->base = STM32_FLASH_BANK_BASE; bank->num_sectors = num_pages; bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors); if (bank->sectors == NULL) { @@ -875,12 +1019,12 @@ static int stm32l4_probe(struct flash_bank *bank) } for (int i = 0; i < bank->num_sectors; i++) { - bank->sectors[i].offset = i * page_size; + bank->sectors[i].offset = i * page_size_kb * 1024; /* in dual bank configuration, if there is a gap between banks * we fix up the sector offset to consider this gap */ if (i >= stm32l4_info->bank1_sectors && stm32l4_info->hole_sectors) - bank->sectors[i].offset += gap_size; - bank->sectors[i].size = page_size; + bank->sectors[i].offset += gap_size_kb * 1024; + bank->sectors[i].size = page_size_kb * 1024; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } @@ -911,18 +1055,20 @@ static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size) rev_str = part_info->revs[i].str; if (rev_str != NULL) { - snprintf(buf, buf_size, "%s - Rev: %s", - part_info->device_str, rev_str); + snprintf(buf, buf_size, "%s - Rev: %s%s", + part_info->device_str, rev_str, stm32l4_info->probed ? + (stm32l4_info->dual_bank_mode ? " dual-bank" : " single-bank") : ""); return ERROR_OK; } } } - snprintf(buf, buf_size, "%s - Rev: unknown (0x%04x)", - part_info->device_str, rev_id); + snprintf(buf, buf_size, "%s - Rev: unknown (0x%04x)%s", + part_info->device_str, rev_id, stm32l4_info->probed ? + (stm32l4_info->dual_bank_mode ? " dual-bank" : " single-bank") : ""); return ERROR_OK; } else { - snprintf(buf, buf_size, "Cannot identify target as an STM32 L4 or WB device"); + snprintf(buf, buf_size, "Cannot identify target as an %s device", device_families); return ERROR_FAIL; } @@ -1073,10 +1219,19 @@ COMMAND_HANDLER(stm32l4_handle_option_load_command) if (ERROR_OK != retval) return retval; - /* Write the OBLLAUNCH bit in CR -> Cause device "POR" and option bytes reload */ - retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_OBLLAUNCH); + /* Set OBL_LAUNCH bit in CR -> system reset and option bytes reload, + * but the RMs explicitly do *NOT* list this as power-on reset cause, and: + * "Note: If the read protection is set while the debugger is still + * connected through JTAG/SWD, apply a POR (power-on reset) instead of a system reset." + */ + retval = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_OBL_LAUNCH); + + command_print(CMD, "stm32l4x option load completed. Power-on reset might be required"); + + /* Need to re-probe after change */ + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + stm32l4_info->probed = false; - command_print(CMD, "stm32l4x option load (POR) completed."); return retval; } diff --git a/src/flash/nor/stm32l4x.h b/src/flash/nor/stm32l4x.h new file mode 100644 index 000000000..abd8010fc --- /dev/null +++ b/src/flash/nor/stm32l4x.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2015 by Uwe Bonnes * + * bon@elektron.ikp.physik.tu-darmstadt.de * + * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef OPENOCD_FLASH_NOR_STM32L4X +#define OPENOCD_FLASH_NOR_STM32L4X + +/* Flash registers offsets */ +#define STM32_FLASH_ACR 0x00 +#define STM32_FLASH_KEYR 0x08 +#define STM32_FLASH_OPTKEYR 0x0c +#define STM32_FLASH_SR 0x10 +#define STM32_FLASH_CR 0x14 +#define STM32_FLASH_OPTR 0x20 +#define STM32_FLASH_WRP1AR 0x2c +#define STM32_FLASH_WRP1BR 0x30 +#define STM32_FLASH_WRP2AR 0x4c +#define STM32_FLASH_WRP2BR 0x50 + +/* FLASH_CR register bits */ +#define FLASH_PG (1 << 0) +#define FLASH_PER (1 << 1) +#define FLASH_MER1 (1 << 2) +#define FLASH_PAGE_SHIFT 3 +#define FLASH_CR_BKER (1 << 11) +#define FLASH_MER2 (1 << 15) +#define FLASH_STRT (1 << 16) +#define FLASH_OPTSTRT (1 << 17) +#define FLASH_EOPIE (1 << 24) +#define FLASH_ERRIE (1 << 25) +#define FLASH_OBL_LAUNCH (1 << 27) +#define FLASH_OPTLOCK (1 << 30) +#define FLASH_LOCK (1 << 31) + +/* FLASH_SR register bits */ +#define FLASH_BSY (1 << 16) + +/* Fast programming not used => related errors not used*/ +#define FLASH_PGSERR (1 << 7) /* Programming sequence error */ +#define FLASH_SIZERR (1 << 6) /* Size error */ +#define FLASH_PGAERR (1 << 5) /* Programming alignment error */ +#define FLASH_WRPERR (1 << 4) /* Write protection error */ +#define FLASH_PROGERR (1 << 3) /* Programming error */ +#define FLASH_OPERR (1 << 1) /* Operation error */ +#define FLASH_EOP (1 << 0) /* End of operation */ +#define FLASH_ERROR (FLASH_PGSERR | FLASH_SIZERR | FLASH_PGAERR | \ + FLASH_WRPERR | FLASH_PROGERR | FLASH_OPERR) + +/* register unlock keys */ +#define KEY1 0x45670123 +#define KEY2 0xCDEF89AB + +/* option register unlock key */ +#define OPTKEY1 0x08192A3B +#define OPTKEY2 0x4C5D6E7F + +#define RDP_LEVEL_0 0xAA +#define RDP_LEVEL_1 0xBB +#define RDP_LEVEL_2 0xCC + +/* other registers */ +#define DBGMCU_IDCODE_G0 0x40015800 +#define DBGMCU_IDCODE_L4_G4 0xE0042000 +#define DBGMCU_IDCODE_L5 0xE0044000 + +#define STM32_FLASH_BANK_BASE 0x08000000 + +#endif diff --git a/tcl/target/stm32g0x.cfg b/tcl/target/stm32g0x.cfg new file mode 100644 index 000000000..50836ea82 --- /dev/null +++ b/tcl/target/stm32g0x.cfg @@ -0,0 +1,88 @@ +# script for stm32g0x family + +# +# stm32g0 devices support SWD transports only. +# +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32g0x +} + +set _ENDIAN little + +# Work-area is a space in RAM used for flash programming +# Smallest proposed target has 8kB ram, use 4kB by default to avoid surprises +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x1000 +} + +#jtag scan chain +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + # Section 37.5.5 - corresponds to Cortex-M0+ + set _CPUTAPID 0x0bc11477 +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME + +# reasonable default +adapter speed 2000 + +adapter srst delay 100 +if {[using_jtag]} { + jtag_ntrst_delay 100 +} + +reset_config srst_nogate + +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +proc stm32g0x_default_reset_start {} { + # Reset clock is HSI16 (16 MHz) + adapter speed 2000 +} + +proc stm32g0x_default_examine_end {} { + # DBGMCU_CR |= DBG_STANDBY | DBG_STOP + mmw 0x40015804 0x00000006 0 + + # Stop watchdog counters during halt + # DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP + mmw 0x40015808 0x00001800 0 +} + +proc stm32g0x_default_reset_init {} { + # Increase clock to 64 Mhz + mmw 0x40022000 0x00000002 0x00000005 ;# FLASH_ACR: Latency = 2 + mww 0x4002100C 0x30000802 ;# RCC_PLLCFGR = PLLR=/2, PLLN=8, PLLM=/1, PLLSRC=0x2 + mmw 0x40021000 0x01000000 0x00000000 ;# RCC_CR |= PLLON + mmw 0x40021008 0x00000002 0x00000005 ;# RCC_CFGR: SW=PLLRCLK + + # Boost JTAG frequency + adapter speed 4000 +} + +# Default hooks +$_TARGETNAME configure -event examine-end { stm32g0x_default_examine_end } +$_TARGETNAME configure -event reset-start { stm32g0x_default_reset_start } +$_TARGETNAME configure -event reset-init { stm32g0x_default_reset_init } diff --git a/tcl/target/stm32g4x.cfg b/tcl/target/stm32g4x.cfg new file mode 100644 index 000000000..9f144a07e --- /dev/null +++ b/tcl/target/stm32g4x.cfg @@ -0,0 +1,103 @@ +# script for stm32g4x family + +# +# stm32g4 devices support both JTAG and SWD transports. +# +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32g4x +} + +set _ENDIAN little + +# Work-area is a space in RAM used for flash programming +# Smallest current target has 32kB ram, use 16kB by default to avoid surprises +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x4000 +} + +#jtag scan chain +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + if { [using_jtag] } { + # See STM Document RM0440 + # Section 46.6.3 - corresponds to Cortex-M4 r0p1 + set _CPUTAPID 0x4ba00477 + } { + set _CPUTAPID 0x2ba01477 + } +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +if {[using_jtag]} { + jtag newtap $_CHIPNAME bs -irlen 5 +} + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME + +if { [info exists QUADSPI] && $QUADSPI } { + set a [llength [flash list]] + set _QSPINAME $_CHIPNAME.qspi + flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000 +} + +# reasonable default +adapter speed 2000 + +adapter srst delay 100 +if {[using_jtag]} { + jtag_ntrst_delay 100 +} + +reset_config srst_nogate + +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +$_TARGETNAME configure -event reset-init { + # CPU comes out of reset with HSION | HSIRDY. + # Use HSI 16 MHz clock, compliant even with VOS == 2. + # 1 WS compliant with VOS == 2 and 16 MHz. + mmw 0x40022000 0x00000001 0x0000000E ;# FLASH_ACR: Latency = 1 + mmw 0x40021000 0x00000100 0x00000000 ;# RCC_CR |= HSION + mmw 0x40021008 0x00000001 0x00000002 ;# RCC_CFGR: SW=HSI16 +} + +$_TARGETNAME configure -event reset-start { + # Reset clock is HSI (16 MHz) + adapter speed 2000 +} + +$_TARGETNAME configure -event examine-end { + # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP + mmw 0xE0042004 0x00000007 0 + + # Stop watchdog counters during halt + # DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP + mmw 0xE0042008 0x00001800 0 +} + +$_TARGETNAME configure -event trace-config { + # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync + # change this value accordingly to configure trace pins + # assignment + mmw 0xE0042004 0x00000020 0 +} From dca1c6ca1f78a6a89e4274e409ff822d655add6b Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Sun, 1 Mar 2020 22:38:50 +0100 Subject: [PATCH 200/354] flash/startup.tcl: add STM32G0 and G4 aliases STM32G0 and G4 uses the same flash driver as the stm32l4x Change-Id: Ic1c4be70aaee809536912e0390f07893efb9a082 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5482 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/startup.tcl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl index 725953486..9d8e91014 100644 --- a/src/flash/startup.tcl +++ b/src/flash/startup.tcl @@ -113,7 +113,9 @@ proc stm32f7x args { eval stm32f2x $args } proc stm32l0x args { eval stm32lx $args } proc stm32l1x args { eval stm32lx $args } -# stm32wb uses the same flash driver as the stm32l4x +# stm32[g0|g4|wb] uses the same flash driver as the stm32l4x +proc stm32g0x args { eval stm32l4x $args } +proc stm32g4x args { eval stm32l4x $args } proc stm32wbx args { eval stm32l4x $args } # ease migration to updated flash driver From aff486b6a05e1413520537d0d257e36e433754fd Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 27 Feb 2020 13:48:15 +0100 Subject: [PATCH 201/354] rtos: Destroy RTOS and fix memory leak The memory leak can be reproduced by using an arbitrary RTOS and valgrind: $ valgrind --leak-check=full --show-leak-kinds=all [...] ==9656== 224 (80 direct, 144 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3 ==9656== at 0x483CD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==9656== by 0x1C541A: os_alloc (rtos.c:79) ==9656== by 0x1C569E: os_alloc_create (rtos.c:111) ==9656== by 0x1C569E: rtos_create (rtos.c:153) ==9656== by 0x1AE332: target_configure (target.c:4899) ==9656== by 0x1AF228: jim_target_configure (target.c:4952) ==9656== by 0x1C9EF9: command_unknown (command.c:1066) ==9656== by 0x313284: JimInvokeCommand (jim.c:10364) ==9656== by 0x313FB6: Jim_EvalObj (jim.c:10814) ==9656== by 0x3154A3: Jim_EvalFile (jim.c:11207) ==9656== by 0x316015: Jim_SourceCoreCommand (jim.c:15230) ==9656== by 0x313284: JimInvokeCommand (jim.c:10364) ==9656== by 0x313B8B: JimEvalObjList (jim.c:10605) [...] Change-Id: I2cd41a154fb8570842601ff4e3e76502f5908f49 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5479 Tested-by: jenkins Reviewed-by: Moritz Fischer Reviewed-by: Tomas Vanek --- src/rtos/rtos.c | 5 +++++ src/rtos/rtos.h | 1 + src/target/target.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 002d7b543..549833f41 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -159,6 +159,11 @@ int rtos_create(Jim_GetOptInfo *goi, struct target *target) return JIM_ERR; } +void rtos_destroy(struct target *target) +{ + os_free(target); +} + int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size) { struct target *target = get_target_from_connection(connection); diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h index a649e2449..c755eec29 100644 --- a/src/rtos/rtos.h +++ b/src/rtos/rtos.h @@ -111,6 +111,7 @@ struct rtos_register_stacking { #define GDB_THREAD_PACKET_NOT_CONSUMED (-40) int rtos_create(Jim_GetOptInfo *goi, struct target *target); +void rtos_destroy(struct target *target); int rtos_set_reg(struct connection *connection, int reg_num, uint8_t *reg_value); int rtos_generic_stack_read(struct target *target, diff --git a/src/target/target.c b/src/target/target.c index ceecaee10..b77400c1f 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -2049,6 +2049,8 @@ static void target_destroy(struct target *target) target->smp = 0; } + rtos_destroy(target); + free(target->gdb_port_override); free(target->type); free(target->trace_info); From 140fe7f7145cb1159e9f530067e8acc62a3584b3 Mon Sep 17 00:00:00 2001 From: Christopher Head Date: Tue, 3 Mar 2020 13:25:50 -0800 Subject: [PATCH 202/354] flash/nor: check fill pattern fits in word size Change-Id: Idad527a428ceed2b53f3da41fb0c64bf8e62614a Signed-off-by: Christopher Head Reviewed-on: http://openocd.zylin.com/5492 Tested-by: jenkins Reviewed-by: Tomas Vanek Reviewed-by: Tarek BOCHKATI --- src/flash/nor/tcl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 3287dd97f..40105b43f 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -512,6 +512,11 @@ COMMAND_HANDLER(handle_flash_fill_command) return ERROR_COMMAND_SYNTAX_ERROR; } + if ((wordsize < sizeof(pattern)) && (pattern >> (8 * wordsize) != 0)) { + command_print(CMD, "Fill pattern 0x%" PRIx64 " does not fit within %" PRIu32 "-byte word", pattern, wordsize); + return ERROR_FAIL; + } + if (count == 0) return ERROR_OK; From 1891c2d26e240a76b2a5a1761ff0da7693d89901 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Tue, 17 Mar 2020 16:31:51 +0100 Subject: [PATCH 203/354] flash/stm32h7x: use proper data type (bool) for has_dual_bank + minor changes in comments' alignment to please our eyes Change-Id: Ifa35a1032afc4e9aee524f596c0298a9eea49c37 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5500 Tested-by: jenkins Reviewed-by: Christopher Head --- src/flash/nor/stm32h7x.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 6edbc00fa..1e2b35159 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -114,13 +114,13 @@ struct stm32h7x_part_info { const struct stm32h7x_rev *revs; size_t num_revs; unsigned int page_size_kb; - unsigned int block_size; /* flash write word size in bytes */ + unsigned int block_size; /* flash write word size in bytes */ uint16_t max_flash_size_kb; - uint8_t has_dual_bank; - uint16_t max_bank_size_kb; /* Used when has_dual_bank is true */ - uint32_t flash_regs_base; /* Flash controller registers location */ - uint32_t fsize_addr; /* Location of FSIZE register */ - uint32_t wps_group_size; /* write protection group sectors' count */ + bool has_dual_bank; + uint16_t max_bank_size_kb; /* Used when has_dual_bank is true */ + uint32_t flash_regs_base; /* Flash controller registers location */ + uint32_t fsize_addr; /* Location of FSIZE register */ + uint32_t wps_group_size; /* write protection group sectors' count */ uint32_t wps_mask; /* function to compute flash_cr register values */ uint32_t (*compute_flash_cr)(uint32_t cmd, int snb); @@ -174,7 +174,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .block_size = 32, .max_flash_size_kb = 2048, .max_bank_size_kb = 1024, - .has_dual_bank = 1, + .has_dual_bank = true, .flash_regs_base = FLASH_REG_BASE_B0, .fsize_addr = 0x1FF1E880, .wps_group_size = 1, @@ -190,7 +190,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .block_size = 16, .max_flash_size_kb = 2048, .max_bank_size_kb = 1024, - .has_dual_bank = 1, + .has_dual_bank = true, .flash_regs_base = FLASH_REG_BASE_B0, .fsize_addr = 0x08FFF80C, .wps_group_size = 4, From 6ecccc88955ead6283bfa9da123e120a73d4cab8 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Fri, 6 Mar 2020 13:52:23 +0100 Subject: [PATCH 204/354] jtag/libusb_helper: permit adapters to compute their custom serials introduce a callback function that could be passed to jtag_libusb_open to permit adapters to compute their custom/exotic serials. the callback should return a non NULL value only when the serial could not be retrieved by the standard 'libusb_get_string_descriptor_ascii' Change-Id: Ib95d6bdfc4ee655eda538fba8becfa183c3b0059 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5496 Reviewed-by: Antonio Borneo Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/jtag/aice/aice_usb.c | 4 +- src/jtag/drivers/ft232r.c | 2 +- src/jtag/drivers/kitprog.c | 2 +- src/jtag/drivers/libusb_helper.c | 39 +++++++++++++++++-- src/jtag/drivers/libusb_helper.h | 8 +++- src/jtag/drivers/opendous.c | 2 +- src/jtag/drivers/openjtag.c | 2 +- src/jtag/drivers/osbdm.c | 2 +- src/jtag/drivers/stlink_usb.c | 3 +- .../usb_blaster/ublast2_access_libusb.c | 8 ++-- 10 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index a5cccfef4..442754209 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -2111,7 +2111,7 @@ static int aice_usb_open(struct aice_port_param_s *param) const uint16_t pids[] = { param->pid, 0 }; struct libusb_device_handle *devh; - if (jtag_libusb_open(vids, pids, NULL, &devh) != ERROR_OK) + if (jtag_libusb_open(vids, pids, NULL, &devh, NULL) != ERROR_OK) return ERROR_FAIL; /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS @@ -2135,7 +2135,7 @@ static int aice_usb_open(struct aice_port_param_s *param) /* reopen jlink after usb_reset * on win32 this may take a second or two to re-enumerate */ int retval; - while ((retval = jtag_libusb_open(vids, pids, NULL, &devh)) != ERROR_OK) { + while ((retval = jtag_libusb_open(vids, pids, NULL, &devh, NULL)) != ERROR_OK) { usleep(1000); timeout--; if (!timeout) diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index 4812362a3..c9ed304a8 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -257,7 +257,7 @@ static int ft232r_init(void) { uint16_t avids[] = {ft232r_vid, 0}; uint16_t apids[] = {ft232r_pid, 0}; - if (jtag_libusb_open(avids, apids, ft232r_serial_desc, &adapter)) { + if (jtag_libusb_open(avids, apids, ft232r_serial_desc, &adapter, NULL)) { LOG_ERROR("ft232r not found: vid=%04x, pid=%04x, serial=%s\n", ft232r_vid, ft232r_pid, (ft232r_serial_desc == NULL) ? "[any]" : ft232r_serial_desc); return ERROR_JTAG_INIT_FAILED; diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index 0c1e74c42..28ed7ac61 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -280,7 +280,7 @@ static int kitprog_usb_open(void) const uint16_t pids[] = { PID, 0 }; if (jtag_libusb_open(vids, pids, kitprog_serial, - &kitprog_handle->usb_handle) != ERROR_OK) { + &kitprog_handle->usb_handle, NULL) != ERROR_OK) { LOG_ERROR("Failed to open or find the device"); return ERROR_FAIL; } diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c index 5a8129cb9..fbbfb4114 100644 --- a/src/jtag/drivers/libusb_helper.c +++ b/src/jtag/drivers/libusb_helper.c @@ -58,7 +58,7 @@ static int jtag_libusb_error(int err) } } -static bool jtag_libusb_match(struct libusb_device_descriptor *dev_desc, +static bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc, const uint16_t vids[], const uint16_t pids[]) { for (unsigned i = 0; vids[i]; i++) { @@ -123,9 +123,40 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in return matched; } +static bool jtag_libusb_match_serial(libusb_device_handle *device, + struct libusb_device_descriptor *dev_desc, const char *serial, + adapter_get_alternate_serial_fn adapter_get_alternate_serial) +{ + if (string_descriptor_equal(device, dev_desc->iSerialNumber, serial)) + return true; + + /* check the alternate serial helper */ + if (!adapter_get_alternate_serial) + return false; + + /* get the alternate serial */ + char *alternate_serial = adapter_get_alternate_serial(device, dev_desc); + + /* check possible failures */ + if (alternate_serial == NULL) + return false; + + /* then compare and free the alternate serial */ + bool match = false; + if (strcmp(serial, alternate_serial) == 0) + match = true; + else + LOG_DEBUG("Device alternate serial number '%s' doesn't match requested serial '%s'", + alternate_serial, serial); + + free(alternate_serial); + return match; +} + int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *serial, - struct libusb_device_handle **out) + struct libusb_device_handle **out, + adapter_get_alternate_serial_fn adapter_get_alternate_serial) { int cnt, idx, errCode; int retval = ERROR_FAIL; @@ -143,7 +174,7 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], if (libusb_get_device_descriptor(devs[idx], &dev_desc) != 0) continue; - if (!jtag_libusb_match(&dev_desc, vids, pids)) + if (!jtag_libusb_match_ids(&dev_desc, vids, pids)) continue; if (jtag_usb_get_location() && !jtag_libusb_location_equal(devs[idx])) @@ -159,7 +190,7 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], /* Device must be open to use libusb_get_string_descriptor_ascii. */ if (serial != NULL && - !string_descriptor_equal(libusb_handle, dev_desc.iSerialNumber, serial)) { + !jtag_libusb_match_serial(libusb_handle, &dev_desc, serial, adapter_get_alternate_serial)) { serial_mismatch = true; libusb_close(libusb_handle); continue; diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h index 46e4954e7..74bb23c52 100644 --- a/src/jtag/drivers/libusb_helper.h +++ b/src/jtag/drivers/libusb_helper.h @@ -22,9 +22,15 @@ #include +/* this callback should return a non NULL value only when the serial could not + * be retrieved by the standard 'libusb_get_string_descriptor_ascii' */ +typedef char * (*adapter_get_alternate_serial_fn)(libusb_device_handle *device, + struct libusb_device_descriptor *dev_desc); + int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *serial, - struct libusb_device_handle **out); + struct libusb_device_handle **out, + adapter_get_alternate_serial_fn adapter_get_alternate_serial); void jtag_libusb_close(struct libusb_device_handle *dev); int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t requestType, uint8_t request, uint16_t wValue, diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index 7298a2a10..6812ef649 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -715,7 +715,7 @@ struct opendous_jtag *opendous_usb_open(void) struct opendous_jtag *result; struct libusb_device_handle *devh; - if (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, NULL, &devh) != ERROR_OK) + if (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, NULL, &devh, NULL) != ERROR_OK) return NULL; jtag_libusb_set_configuration(devh, 0); diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 6131df914..7eab5c130 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -449,7 +449,7 @@ static int openjtag_init_cy7c65215(void) int ret; usbh = NULL; - ret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, NULL, &usbh); + ret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, NULL, &usbh, NULL); if (ret != ERROR_OK) { LOG_ERROR("unable to open cy7c65215 device"); goto err; diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index aea126d0d..dc236660e 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -374,7 +374,7 @@ static int osbdm_flush(struct osbdm *osbdm, struct queue *queue) static int osbdm_open(struct osbdm *osbdm) { (void)memset(osbdm, 0, sizeof(*osbdm)); - if (jtag_libusb_open(osbdm_vid, osbdm_pid, NULL, &osbdm->devh) != ERROR_OK) + if (jtag_libusb_open(osbdm_vid, osbdm_pid, NULL, &osbdm->devh, NULL) != ERROR_OK) return ERROR_FAIL; if (libusb_claim_interface(osbdm->devh, 0) != ERROR_OK) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index ca7a4df4e..d8d8d67e3 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -2778,7 +2778,8 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) in order to become operational. */ do { - if (jtag_libusb_open(param->vid, param->pid, param->serial, &h->fd) != ERROR_OK) { + if (jtag_libusb_open(param->vid, param->pid, param->serial, + &h->fd, NULL) != ERROR_OK) { LOG_ERROR("open failed"); goto error_open; } diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c index 4f7ee6300..b406c0321 100644 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c @@ -195,7 +195,7 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low) bool renumeration = false; int ret; - if (jtag_libusb_open(vids, pids, NULL, &temp) == ERROR_OK) { + if (jtag_libusb_open(vids, pids, NULL, &temp, NULL) == ERROR_OK) { LOG_INFO("Altera USB-Blaster II (uninitialized) found"); LOG_INFO("Loading firmware..."); ret = load_usb_blaster_firmware(temp, low); @@ -209,13 +209,15 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low) const uint16_t pids_renum[] = { low->ublast_pid, 0 }; if (renumeration == false) { - if (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK) { + if (jtag_libusb_open(vids_renum, pids_renum, NULL, + &low->libusb_dev, NULL) != ERROR_OK) { LOG_ERROR("Altera USB-Blaster II not found"); return ERROR_FAIL; } } else { int retry = 10; - while (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK && retry--) { + while (jtag_libusb_open(vids_renum, pids_renum, NULL, + &low->libusb_dev, NULL) != ERROR_OK && retry--) { usleep(1000000); LOG_INFO("Waiting for renumerate..."); } From 4b4389a2d69d96e08d2b417e47c24cad6b50a5c5 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Sat, 7 Mar 2020 17:20:24 +0100 Subject: [PATCH 205/354] stlink: workaround serial bug with old ST-Link DFU Old ST-LINK DFU returns an incorrect serial in the USB descriptor example for the following serial "57FF72067265575742132067" - the correct descriptor serial is: 0x32, 0x03, 0x35, 0x00, 0x37, 0x00, 0x46, 0x00, 0x46, 0x00 ... this contains the length (0x32 = 50), the type (0x3 = DT_STRING) and the serial in unicode format. the serial part is: 0x0035, 0x0037, 0x0046, 0x0046 ... >> 57FF ... this format could be read correctly by 'libusb_get_string_descriptor_ascii' so this case is managed by libusb_helper::string_descriptor_equal - the buggy DFU is not doing any unicode conversion and returns a raw serial data in the descriptor: 0x1a, 0x03, 0x57, 0x00, 0xFF, 0x00, 0x72, 0x00 ... >> 57 FF 72 ... based on the length (0x1a = 26) we could easily decide if we have to fixup the serial and then we have just to convert the raw data into printable characters using sprintf example for an old ST-LINK/V2 standalone: before : 'W?rreWWB g' after : '57FF72067265575742132067' => same as the displayed value in STM32CubeProgrammer tested using these commands using the buggy serial -c "hla_serial \x57\x3f\x72\x06\x72\x65\x57\x57\x42\x13\x20\x67" using the computed serial -c "hla_serial 57FF72067265575742132067" Change-Id: I1213818257663eeb8e76f419087d3127d0524842 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5396 Reviewed-by: Oleksij Rempel Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/stlink_usb.c | 83 ++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index d8d8d67e3..6ab979f1c 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -47,6 +47,8 @@ #define USE_LIBUSB_ASYNCIO #endif +#define STLINK_SERIAL_LEN 24 + #define ENDPOINT_IN 0x80 #define ENDPOINT_OUT 0x00 @@ -2745,6 +2747,85 @@ static int stlink_usb_close(void *handle) return ERROR_OK; } +/* Compute ST-Link serial number from the device descriptor + * this function will help to work-around a bug in old ST-Link/V2 DFU + * the buggy DFU returns an incorrect serial in the USB descriptor + * example for the following serial "57FF72067265575742132067" + * - the correct descriptor serial is: + * 0x32, 0x03, 0x35, 0x00, 0x37, 0x00, 0x46, 0x00, 0x46, 0x00, 0x37, 0x00, 0x32, 0x00 ... + * this contains the length (0x32 = 50), the type (0x3 = DT_STRING) and the serial in unicode format + * the serial part is: 0x0035, 0x0037, 0x0046, 0x0046, 0x0037, 0x0032 ... >> 57FF72 ... + * this format could be read correctly by 'libusb_get_string_descriptor_ascii' + * so this case is managed by libusb_helper::string_descriptor_equal + * - the buggy DFU is not doing any unicode conversion and returns a raw serial data in the descriptor + * 0x1a, 0x03, 0x57, 0x00, 0xFF, 0x00, 0x72, 0x00 ... + * >> 57 FF 72 ... + * based on the length (0x1a = 26) we could easily decide if we have to fixup the serial + * and then we have just to convert the raw data into printable characters using sprintf + */ +char *stlink_usb_get_alternate_serial(libusb_device_handle *device, + struct libusb_device_descriptor *dev_desc) +{ + int usb_retval; + unsigned char desc_serial[(STLINK_SERIAL_LEN + 1) * 2]; + + if (dev_desc->iSerialNumber == 0) + return NULL; + + /* get the LANGID from String Descriptor Zero */ + usb_retval = libusb_get_string_descriptor(device, 0, 0, desc_serial, + sizeof(desc_serial)); + + if (usb_retval < LIBUSB_SUCCESS) { + LOG_ERROR("libusb_get_string_descriptor() failed: %s(%d)", + libusb_error_name(usb_retval), usb_retval); + return NULL; + } else if (usb_retval < 4) { + /* the size should be least 4 bytes to contain a minimum of 1 supported LANGID */ + LOG_ERROR("could not get the LANGID"); + return NULL; + } + + uint32_t langid = desc_serial[2] | (desc_serial[3] << 8); + + /* get the serial */ + usb_retval = libusb_get_string_descriptor(device, dev_desc->iSerialNumber, + langid, desc_serial, sizeof(desc_serial)); + + unsigned char len = desc_serial[0]; + + if (usb_retval < LIBUSB_SUCCESS) { + LOG_ERROR("libusb_get_string_descriptor() failed: %s(%d)", + libusb_error_name(usb_retval), usb_retval); + return NULL; + } else if (desc_serial[1] != LIBUSB_DT_STRING || len > usb_retval) { + LOG_ERROR("invalid string in ST-LINK USB serial descriptor"); + return NULL; + } + + if (len == ((STLINK_SERIAL_LEN + 1) * 2)) { + /* good ST-Link adapter, this case is managed by + * libusb::libusb_get_string_descriptor_ascii */ + return NULL; + } else if (len != ((STLINK_SERIAL_LEN / 2 + 1) * 2)) { + LOG_ERROR("unexpected serial length (%d) in descriptor", len); + return NULL; + } + + /* else (len == 26) => buggy ST-Link */ + + char *alternate_serial = malloc((STLINK_SERIAL_LEN + 1) * sizeof(char)); + if (alternate_serial == NULL) + return NULL; + + for (unsigned int i = 0; i < STLINK_SERIAL_LEN; i += 2) + sprintf(alternate_serial + i, "%02X", desc_serial[i + 2]); + + alternate_serial[STLINK_SERIAL_LEN] = '\0'; + + return alternate_serial; +} + /** */ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) { @@ -2779,7 +2860,7 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) */ do { if (jtag_libusb_open(param->vid, param->pid, param->serial, - &h->fd, NULL) != ERROR_OK) { + &h->fd, stlink_usb_get_alternate_serial) != ERROR_OK) { LOG_ERROR("open failed"); goto error_open; } From c999fcef3e96fbdb5226b0913bddf29365566ce8 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 9 Mar 2020 15:10:17 +0100 Subject: [PATCH 206/354] flash/stm32l4x: add support of STM32WLEx devices STM32WLEx devices are based on arm Cortex-M4 running at 48MHz, contains a single bank of maximum 256 Kbytes of flash memory. there is 3 variants with different Flash/RAM sizes: STM32WLE5JC : 256K/64K STM32WLE5JB : 128K/48K STM32WLE5J8 : 64K/20K the work-area size is set to 20 kb to fit in STM32WLE5J8 Change-Id: Ie8e186fe4be97cbc25c53ef0ade4b4dbbcee6f66 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5450 Tested-by: jenkins Reviewed-by: Andreas Bolsch Reviewed-by: Tomas Vanek --- doc/openocd.texi | 2 +- src/flash/nor/stm32l4x.c | 23 ++++++++- src/flash/startup.tcl | 3 +- tcl/target/stm32wlx.cfg | 100 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 tcl/target/stm32wlx.cfg diff --git a/doc/openocd.texi b/doc/openocd.texi index 97c5a728d..25554f87a 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6892,7 +6892,7 @@ The @var{num} parameter is a value shown by @command{flash banks}. @end deffn @deffn {Flash Driver} stm32l4x -All members of the STM32L4, STM32L4+, STM32WB and STM32G4 +All members of the STM32L4, STM32L4+, STM32WB, STM32WL and STM32G4 microcontroller families from STMicroelectronics include internal flash and use ARM Cortex-M4 cores. Additionally this driver supports STM32G0 family with ARM Cortex-M0+ core. diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index b6f0d714d..42f3394ec 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -75,6 +75,12 @@ * http://www.st.com/resource/en/reference_manual/dm00622834.pdf */ +/* STM32WLxxx series for reference. + * + * RM0461 (STM32WLEx) + * http://www.st.com/resource/en/reference_manual/dm00530369.pdf + */ + /* * STM32G0xxx series for reference. * @@ -132,7 +138,7 @@ struct stm32l4_flash_bank { }; /* human readable list of families this drivers supports */ -static const char *device_families = "STM32L4/L4+/WB/G4/G0"; +static const char *device_families = "STM32L4/L4+/WB/WL/G4/G0"; static const struct stm32l4_rev stm32_415_revs[] = { { 0x1000, "1" }, { 0x1001, "2" }, { 0x1003, "3" }, { 0x1007, "4" } @@ -182,6 +188,10 @@ static const struct stm32l4_rev stm32_495_revs[] = { { 0x2001, "2.1" }, }; +static const struct stm32l4_rev stm32_497_revs[] = { + { 0x1000, "1.0" }, +}; + static const struct stm32l4_part_info stm32l4_parts[] = { { .id = 0x415, @@ -303,6 +313,16 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .flash_regs_base = 0x58004000, .fsize_addr = 0x1FFF75E0, }, + { + .id = 0x497, + .revs = stm32_497_revs, + .num_revs = ARRAY_SIZE(stm32_497_revs), + .device_str = "STM32WLEx", + .max_flash_size_kb = 256, + .has_dual_bank = false, + .flash_regs_base = 0x58004000, + .fsize_addr = 0x1FFF75E0, + }, }; /* flash bank stm32l4x 0 0 */ @@ -918,6 +938,7 @@ static int stm32l4_probe(struct flash_bank *bank) case 0x464: /* STM32L41/L42xx */ case 0x466: /* STM32G03/G04xx */ case 0x468: /* STM32G43/G44xx */ + case 0x497: /* STM32WLEx */ /* single bank flash */ page_size_kb = 2; num_pages = flash_size_kb / page_size_kb; diff --git a/src/flash/startup.tcl b/src/flash/startup.tcl index 9d8e91014..aafb939cd 100644 --- a/src/flash/startup.tcl +++ b/src/flash/startup.tcl @@ -113,10 +113,11 @@ proc stm32f7x args { eval stm32f2x $args } proc stm32l0x args { eval stm32lx $args } proc stm32l1x args { eval stm32lx $args } -# stm32[g0|g4|wb] uses the same flash driver as the stm32l4x +# stm32[g0|g4|wb|wl] uses the same flash driver as the stm32l4x proc stm32g0x args { eval stm32l4x $args } proc stm32g4x args { eval stm32l4x $args } proc stm32wbx args { eval stm32l4x $args } +proc stm32wlx args { eval stm32l4x $args } # ease migration to updated flash driver proc stm32x args { diff --git a/tcl/target/stm32wlx.cfg b/tcl/target/stm32wlx.cfg new file mode 100644 index 000000000..98c9a7ee9 --- /dev/null +++ b/tcl/target/stm32wlx.cfg @@ -0,0 +1,100 @@ +# script for stm32wlx family + +# +# stm32wl devices support both JTAG and SWD transports. +# +source [find target/swj-dp.tcl] +source [find mem_helper.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32wlx +} + +set _ENDIAN little + +# Work-area is a space in RAM used for flash programming +# By default use 20kB +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x5000 +} + +#jtag scan chain +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + if { [using_jtag] } { + set _CPUTAPID 0x6ba00477 + } else { + # SWD IDCODE (single drop, arm) + set _CPUTAPID 0x6ba02477 + } +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +if {[using_jtag]} { + swj_newdap $_CHIPNAME bs -irlen 5 +} + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME + +# Common knowledges tells JTAG speed should be <= F_CPU/6. +# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on +# the safe side. +# +# Note that there is a pretty wide band where things are +# more or less stable, see http://openocd.zylin.com/#/c/3366/ +adapter speed 500 + +adapter srst delay 100 +if {[using_jtag]} { + jtag_ntrst_delay 100 +} + +reset_config srst_nogate + +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +$_TARGETNAME configure -event reset-init { + # CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz. + # Configure system to use MSI 24 MHz clock, compliant with VOS default Range1. + # 2 WS compliant with VOS=Range1 and 24 MHz. + mmw 0x58004000 0x00000102 0 ;# FLASH_ACR |= PRFTEN | 2(Latency) + mmw 0x58000000 0x00000091 0 ;# RCC_CR = MSI_ON | MSI Range 24 MHz + # Boost JTAG frequency + adapter speed 4000 +} + +$_TARGETNAME configure -event reset-start { + # Reset clock is MSI (4 MHz) + adapter speed 500 +} + +$_TARGETNAME configure -event examine-end { + # Enable debug during low power modes (uses more power) + # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP + mmw 0xE0042004 0x00000007 0 + + # Stop watchdog counters during halt + # DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP + mmw 0xE004203C 0x00001800 0 +} + +$_TARGETNAME configure -event trace-config { + # nothing to do +} From bff1b6f05a56eed8e150c25d925bd51ca2840daf Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 9 Mar 2020 13:33:08 +0100 Subject: [PATCH 207/354] flash/stm32l4x: add support of STM32WB3x devices STM32WB3x devices' flash are quite similar to STM32WB5x, except the maximum flash size, which is 512K for WB3x and 1M for WB5x Change-Id: I3098d7153a7429e0e72c75cec962c05768b0b018 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5475 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/stm32l4x.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 42f3394ec..2cc378a90 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -188,6 +188,10 @@ static const struct stm32l4_rev stm32_495_revs[] = { { 0x2001, "2.1" }, }; +static const struct stm32l4_rev stm32_496_revs[] = { + { 0x1000, "A" }, +}; + static const struct stm32l4_rev stm32_497_revs[] = { { 0x1000, "1.0" }, }; @@ -313,6 +317,16 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .flash_regs_base = 0x58004000, .fsize_addr = 0x1FFF75E0, }, + { + .id = 0x496, + .revs = stm32_496_revs, + .num_revs = ARRAY_SIZE(stm32_496_revs), + .device_str = "STM32WB3x", + .max_flash_size_kb = 512, + .has_dual_bank = false, + .flash_regs_base = 0x58004000, + .fsize_addr = 0x1FFF75E0, + }, { .id = 0x497, .revs = stm32_497_revs, @@ -985,6 +999,7 @@ static int stm32l4_probe(struct flash_bank *bank) } break; case 0x495: /* STM32WB5x */ + case 0x496: /* STM32WB3x */ /* single bank flash */ page_size_kb = 4; num_pages = flash_size_kb / page_size_kb; From c9ebd488eadfaec6154db5747f376323f587766d Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Wed, 4 Mar 2020 13:07:13 -0600 Subject: [PATCH 208/354] drivers: xds110: Add support TCK changes in firmware update Starting with XDS110 firmware version 3.0.0.0, the peak TCK frequency became 14,000 kHz. So the delay count calculation in the current driver has been updated to use the new formula for setting the TCK speed depending on which version of the firmware is detected. And because of the changes, the default TCK settings for the XDS110 based Launchpads can be adjusted to take advantage of the higher TCK performance. Note that the values used have been determined through testing in the automated test labs to be the highest TCK frequency with the XDS110 that are still reliable. Different boards have a different peak TCK setting that should be safe. Change-Id: I4d66e90d8fac8272641ba4db4a3a510e3b444d86 Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5493 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/xds110.c | 156 ++++++++++++++++++++-------- tcl/board/ti_cc13x0_launchpad.cfg | 2 +- tcl/board/ti_cc13x2_launchpad.cfg | 2 +- tcl/board/ti_cc26x0_launchpad.cfg | 2 +- tcl/board/ti_cc26x2_launchpad.cfg | 2 +- tcl/board/ti_cc3220sf_launchpad.cfg | 2 +- tcl/board/ti_cc32xx_launchpad.cfg | 2 +- tcl/board/ti_msp432_launchpad.cfg | 2 +- 8 files changed, 118 insertions(+), 52 deletions(-) diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index 69d989520..085d85f4c 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -41,6 +41,12 @@ #define OCD_FIRMWARE_UPGRADE \ "XDS110: upgrade to version 2.3.0.11+ for improved support" +/* Firmware version that introduced improved TCK performance */ +#define FAST_TCK_FIRMWARE_VERSION 0x03000000 + +/* Firmware version that introduced 10 MHz and 12 MHz TCK support */ +#define FAST_TCK_PLUS_FIRMWARE_VERSION 0x03000003 + /*************************************************************************** * USB Connection Buffer Definitions * ***************************************************************************/ @@ -91,8 +97,17 @@ /* TCK frequency limits */ #define XDS110_MIN_TCK_SPEED 100 /* kHz */ -#define XDS110_MAX_TCK_SPEED 2500 /* kHz */ -#define XDS110_TCK_PULSE_INCREMENT 66.0 +#define XDS110_MAX_SLOW_TCK_SPEED 2500 /* kHz */ +#define XDS110_MAX_FAST_TCK_SPEED 14000 /* kHz */ +#define XDS110_DEFAULT_TCK_SPEED 2500 /* kHz */ + +/* Fixed TCK delay values for "Fast" TCK frequencies */ +#define FAST_TCK_DELAY_14000_KHZ 0 +#define FAST_TCK_DELAY_10000_KHZ 0xfffffffd +#define FAST_TCK_DELAY_12000_KHZ 0xfffffffe +#define FAST_TCK_DELAY_8500_KHZ 1 +#define FAST_TCK_DELAY_5500_KHZ 2 +/* For TCK frequencies below 5500 kHz, use calculated delay */ /* Scan mode on connect */ #define MODE_JTAG 1 @@ -249,7 +264,7 @@ static struct xds110_info xds110 = { .is_cmapi_acquired = false, .is_swd_mode = false, .is_ap_dirty = false, - .speed = XDS110_MAX_TCK_SPEED, + .speed = XDS110_DEFAULT_TCK_SPEED, .delay_count = 0, .serial = {0}, .voltage = 0, @@ -1846,6 +1861,8 @@ static int xds110_execute_queue(void) static int xds110_speed(int speed) { + double freq_to_use; + uint32_t delay_count; bool success; if (speed == 0) { @@ -1853,61 +1870,110 @@ static int xds110_speed(int speed) return ERROR_JTAG_NOT_IMPLEMENTED; } - if (speed > XDS110_MAX_TCK_SPEED) { - LOG_INFO("XDS110: reduce speed request: %dkHz to %dkHz maximum", - speed, XDS110_MAX_TCK_SPEED); - speed = XDS110_MAX_TCK_SPEED; - } - if (speed < XDS110_MIN_TCK_SPEED) { - LOG_INFO("XDS110: increase speed request: %dkHz to %dkHz minimum", + LOG_INFO("XDS110: increase speed request: %d kHz to %d kHz minimum", speed, XDS110_MIN_TCK_SPEED); speed = XDS110_MIN_TCK_SPEED; } - /* The default is the maximum frequency the XDS110 can support */ - uint32_t freq_to_use = XDS110_MAX_TCK_SPEED * 1000; /* Hz */ - uint32_t delay_count = 0; + /* Older XDS110 firmware had inefficient scan routines and could only */ + /* achieve a peak TCK frequency of about 2500 kHz */ + if (xds110.firmware < FAST_TCK_FIRMWARE_VERSION) { - if (XDS110_MAX_TCK_SPEED != speed) { - freq_to_use = speed * 1000; /* Hz */ + /* Check for request for top speed or higher */ + if (speed >= XDS110_MAX_SLOW_TCK_SPEED) { - /* Calculate the delay count value */ - double one_giga = 1000000000; - /* Get the pulse duration for the maximum frequency supported in ns */ - double max_freq_pulse_duration = one_giga / - (XDS110_MAX_TCK_SPEED * 1000); + /* Inform user that speed was adjusted down to max possible */ + if (speed > XDS110_MAX_SLOW_TCK_SPEED) { + LOG_INFO( + "XDS110: reduce speed request: %d kHz to %d kHz maximum", + speed, XDS110_MAX_SLOW_TCK_SPEED); + speed = XDS110_MAX_SLOW_TCK_SPEED; + } + delay_count = 0; - /* Convert frequency to pulse duration */ - double freq_to_pulse_width_in_ns = one_giga / freq_to_use; + } else { - /* - * Start with the pulse duration for the maximum frequency. Keep - * decrementing the time added by each count value till the requested - * frequency pulse is less than the calculated value. - */ - double current_value = max_freq_pulse_duration; + const double XDS110_TCK_PULSE_INCREMENT = 66.0; + freq_to_use = speed * 1000; /* Hz */ + delay_count = 0; - while (current_value < freq_to_pulse_width_in_ns) { - current_value += XDS110_TCK_PULSE_INCREMENT; - ++delay_count; + /* Calculate the delay count value */ + double one_giga = 1000000000; + /* Get the pulse duration for the max frequency supported in ns */ + double max_freq_pulse_duration = one_giga / + (XDS110_MAX_SLOW_TCK_SPEED * 1000); + + /* Convert frequency to pulse duration */ + double freq_to_pulse_width_in_ns = one_giga / freq_to_use; + + /* + * Start with the pulse duration for the maximum frequency. Keep + * decrementing time added by each count value till the requested + * frequency pulse is less than the calculated value. + */ + double current_value = max_freq_pulse_duration; + + while (current_value < freq_to_pulse_width_in_ns) { + current_value += XDS110_TCK_PULSE_INCREMENT; + ++delay_count; + } + + /* + * Determine which delay count yields the best match. + * The one obtained above or one less. + */ + if (delay_count) { + double diff_freq_1 = freq_to_use - + (one_giga / (max_freq_pulse_duration + + (XDS110_TCK_PULSE_INCREMENT * delay_count))); + double diff_freq_2 = (one_giga / (max_freq_pulse_duration + + (XDS110_TCK_PULSE_INCREMENT * (delay_count - 1)))) - + freq_to_use; + + /* One less count value yields a better match */ + if (diff_freq_1 > diff_freq_2) + --delay_count; + } } - /* - * Determine which delay count yields the best match. - * The one obtained above or one less. - */ - if (delay_count) { - double diff_freq_1 = freq_to_use - - (one_giga / (max_freq_pulse_duration + - (XDS110_TCK_PULSE_INCREMENT * delay_count))); - double diff_freq_2 = (one_giga / (max_freq_pulse_duration + - (XDS110_TCK_PULSE_INCREMENT * (delay_count - 1)))) - - freq_to_use; + /* Newer firmware has reworked TCK routines that are much more efficient */ + /* and can now achieve a peak TCK frequency of 14000 kHz */ + } else { - /* One less count value yields a better match */ - if (diff_freq_1 > diff_freq_2) - --delay_count; + if (speed >= XDS110_MAX_FAST_TCK_SPEED) { + if (speed > XDS110_MAX_FAST_TCK_SPEED) { + LOG_INFO( + "XDS110: reduce speed request: %d kHz to %d kHz maximum", + speed, XDS110_MAX_FAST_TCK_SPEED); + speed = XDS110_MAX_FAST_TCK_SPEED; + } + delay_count = 0; + } else if (speed >= 12000 && xds110.firmware >= + FAST_TCK_PLUS_FIRMWARE_VERSION) { + delay_count = FAST_TCK_DELAY_12000_KHZ; + } else if (speed >= 10000 && xds110.firmware >= + FAST_TCK_PLUS_FIRMWARE_VERSION) { + delay_count = FAST_TCK_DELAY_10000_KHZ; + } else if (speed >= 8500) { + delay_count = FAST_TCK_DELAY_8500_KHZ; + } else if (speed >= 5500) { + delay_count = FAST_TCK_DELAY_5500_KHZ; + } else { + /* Calculate the delay count to set the frequency */ + /* Formula determined by measuring the waveform on Saeleae logic */ + /* analyzer using known values for delay count */ + const double m = 17100000.0; /* slope */ + const double b = -1.02; /* y-intercept */ + + freq_to_use = speed * 1000; /* Hz */ + double period = 1.0/freq_to_use; + double delay = m * period + b; + + if (delay < 1.0) + delay_count = 1; + else + delay_count = (uint32_t)delay; } } diff --git a/tcl/board/ti_cc13x0_launchpad.cfg b/tcl/board/ti_cc13x0_launchpad.cfg index d2d0c68fe..4fbce4120 100644 --- a/tcl/board/ti_cc13x0_launchpad.cfg +++ b/tcl/board/ti_cc13x0_launchpad.cfg @@ -3,5 +3,5 @@ # source [find interface/xds110.cfg] transport select jtag -adapter speed 2500 +adapter speed 5500 source [find target/ti_cc13x0.cfg] diff --git a/tcl/board/ti_cc13x2_launchpad.cfg b/tcl/board/ti_cc13x2_launchpad.cfg index 706bb728a..dc0c18230 100644 --- a/tcl/board/ti_cc13x2_launchpad.cfg +++ b/tcl/board/ti_cc13x2_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC13x2 LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter speed 2500 +adapter speed 5500 transport select jtag source [find target/ti_cc13x2.cfg] diff --git a/tcl/board/ti_cc26x0_launchpad.cfg b/tcl/board/ti_cc26x0_launchpad.cfg index c16fa4c56..372e57ceb 100644 --- a/tcl/board/ti_cc26x0_launchpad.cfg +++ b/tcl/board/ti_cc26x0_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC26x0 LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter speed 2500 +adapter speed 5500 transport select jtag source [find target/ti_cc26x0.cfg] diff --git a/tcl/board/ti_cc26x2_launchpad.cfg b/tcl/board/ti_cc26x2_launchpad.cfg index e7941914c..c8057ad3d 100644 --- a/tcl/board/ti_cc26x2_launchpad.cfg +++ b/tcl/board/ti_cc26x2_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC26x2 LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter speed 2500 +adapter speed 5500 transport select jtag source [find target/ti_cc26x2.cfg] diff --git a/tcl/board/ti_cc3220sf_launchpad.cfg b/tcl/board/ti_cc3220sf_launchpad.cfg index 30255c793..7c8310af0 100644 --- a/tcl/board/ti_cc3220sf_launchpad.cfg +++ b/tcl/board/ti_cc3220sf_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC3220SF-LaunchXL LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter speed 2500 +adapter speed 8500 transport select swd source [find target/ti_cc3220sf.cfg] diff --git a/tcl/board/ti_cc32xx_launchpad.cfg b/tcl/board/ti_cc32xx_launchpad.cfg index 6676e5d6e..1df461a93 100644 --- a/tcl/board/ti_cc32xx_launchpad.cfg +++ b/tcl/board/ti_cc32xx_launchpad.cfg @@ -2,6 +2,6 @@ # TI CC32xx-LaunchXL LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter speed 2500 +adapter speed 8500 transport select swd source [find target/ti_cc32xx.cfg] diff --git a/tcl/board/ti_msp432_launchpad.cfg b/tcl/board/ti_msp432_launchpad.cfg index f7c96eed1..6d2b15dd4 100644 --- a/tcl/board/ti_msp432_launchpad.cfg +++ b/tcl/board/ti_msp432_launchpad.cfg @@ -2,6 +2,6 @@ # TI MSP432 LaunchPad Evaluation Kit # source [find interface/xds110.cfg] -adapter speed 2500 +adapter speed 10000 transport select swd source [find target/ti_msp432.cfg] From 76ba9bd0b373e0bddfe944e411550b0a0304b238 Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Mon, 2 Mar 2020 12:22:12 -0600 Subject: [PATCH 209/354] tcl/target: Use sysresetreq for MSP432 targets Confirmed that sysresetreq is supported and works better for MSP432P4 and MSP432E4 targets than srst that was previously being used. Tested on MSP432P4111, MSP432P401R, and MSP432E401Y Launchpads. Change-Id: I1454c3379b9300bc133f82a766daeaefb98dbaac Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5488 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/target/ti_msp432.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tcl/target/ti_msp432.cfg b/tcl/target/ti_msp432.cfg index 146e7ee21..77f81da69 100644 --- a/tcl/target/ti_msp432.cfg +++ b/tcl/target/ti_msp432.cfg @@ -42,10 +42,10 @@ if { [info exists WORKAREASIZE] } { set _WORKAREASIZE 0x4000 } + $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME -reset_config srst_only -adapter srst delay 100 +cortex_m reset_config sysresetreq From 87a4158acf56863d4e5e70afc33791f631b6c693 Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Wed, 4 Mar 2020 17:24:33 -0600 Subject: [PATCH 210/354] drivers: xds110: Clean up command syntax and documentation Arrange all commands under a top level xds110 command. Fix documentation to properly reflect the current functionality. Also updated the links in the document to the new permanent links for the XDS110 only support. Patch updated for comments from code review. Return ERROR_COMMAND_SYNTAX_ERROR for wrong number of args in commands. Added deprecated commands to src/jtag/startup.tcl. Change-Id: Ica45f65e1fdf7fa72866f4e28c4f6bce428d8ac9 Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5495 Tested-by: jenkins Reviewed-by: Antonio Borneo --- doc/openocd.texi | 28 ++++++++++++++++-------- src/jtag/drivers/xds110.c | 46 +++++++++++++++++---------------------- src/jtag/startup.tcl | 10 +++++++++ 3 files changed, 49 insertions(+), 35 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 25554f87a..4665092d1 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -537,15 +537,25 @@ debuggers to ARM Cortex based targets @url{http://www.keil.com/support/man/docs/ @item @b{TI XDS110 Debug Probe} @* The XDS110 is included as the embedded debug probe on many Texas Instruments -LaunchPad evaluation boards. -@* The XDS110 is also available as a stand-alone USB debug probe. The XDS110 -stand-alone probe has the additional ability to supply voltage to the target -board via its AUX FUNCTIONS port. Use the -@command{xds110_supply_voltage } command to set the voltage. 0 turns -off the supply. Otherwise, the supply can be set to any value in the range 1800 -to 3600 millivolts. -@* Link: @url{http://processors.wiki.ti.com/index.php/XDS110} -@* Link: @url{http://processors.wiki.ti.com/index.php/XDS_Emulation_Software_Package#XDS110_Support_Utilities} +LaunchPad evaluation boards. The XDS110 is also available as a stand-alone USB +debug probe with the added capability to supply power to the target board. The +following commands are supported by the XDS110 driver: +@*@deffn {Config Command} {xds110 serial} serial_string +Specifies the serial number of which XDS110 probe to use. Otherwise, the first +XDS110 found will be used. +@end deffn +@*@deffn {Config Command} {xds110 supply} voltage_in_millivolts +Available only on the XDS110 stand-alone probe. Sets the voltage level of the +XDS110 power supply. A value of 0 leaves the supply off. Otherwise, the supply +can be set to any value in the range 1800 to 3600 millivolts. +@end deffn +@*@deffn {Command} {xds110 info} +Displays information about the connected XDS110 debug probe (e.g. firmware +version). +@end deffn +@* Further information can be found at the following sites: +@* Link: @url{https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds110.html} +@* Link: @url{https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds_software_package_download.html#xds110-support-utilities} @end itemize @section IBM PC Parallel Printer Port Based diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index 085d85f4c..9ca200e79 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -2028,11 +2028,8 @@ COMMAND_HANDLER(xds110_handle_serial_command) xds110.serial[i] = (char)serial[i]; xds110.serial[len] = 0; - } else { - LOG_ERROR("XDS110: expected exactly one argument to xds110_serial " - ""); - return ERROR_FAIL; - } + } else + return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_OK; } @@ -2053,11 +2050,8 @@ COMMAND_HANDLER(xds110_handle_supply_voltage_command) return ERROR_FAIL; } xds110.voltage = voltage; - } else { - LOG_ERROR("XDS110: expected one argument to xds110_supply_voltage " - ""); - return ERROR_FAIL; - } + } else + return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_OK; } @@ -2067,8 +2061,22 @@ static const struct command_registration xds110_subcommand_handlers[] = { .name = "info", .handler = &xds110_handle_info_command, .mode = COMMAND_EXEC, - .usage = "", .help = "show XDS110 info", + .usage = "", + }, + { + .name = "serial", + .handler = &xds110_handle_serial_command, + .mode = COMMAND_CONFIG, + .help = "set the XDS110 probe serial number", + .usage = "serial_string", + }, + { + .name = "supply", + .handler = &xds110_handle_supply_voltage_command, + .mode = COMMAND_CONFIG, + .help = "set the XDS110 probe supply voltage", + .usage = "voltage_in_millivolts", }, COMMAND_REGISTRATION_DONE }; @@ -2078,23 +2086,9 @@ static const struct command_registration xds110_command_handlers[] = { .name = "xds110", .mode = COMMAND_ANY, .help = "perform XDS110 management", - .usage = "", + .usage = "", .chain = xds110_subcommand_handlers, }, - { - .name = "xds110_serial", - .handler = &xds110_handle_serial_command, - .mode = COMMAND_CONFIG, - .help = "set the XDS110 probe serial number", - .usage = "serial_string", - }, - { - .name = "xds110_supply_voltage", - .handler = &xds110_handle_supply_voltage_command, - .mode = COMMAND_CONFIG, - .help = "set the XDS110 probe supply voltage", - .usage = "supply_voltage (millivolts)", - }, COMMAND_REGISTRATION_DONE }; diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl index 8fc3ad5ef..f8c4ca0bf 100644 --- a/src/jtag/startup.tcl +++ b/src/jtag/startup.tcl @@ -216,4 +216,14 @@ proc ftdi_location args { eval adapter usb location $args } +proc xds110_serial args { + echo "DEPRECATED! use 'xds110 serial' not 'xds110_serial'" + eval xds110 serial $args +} + +proc xds110_supply_voltage args { + echo "DEPRECATED! use 'xds110 supply' not 'xds110_supply_voltage'" + eval xds110 supply $args +} + # END MIGRATION AIDS From d35c44c743d6f471697ed1d204fe5447fd47cefd Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Wed, 4 Mar 2020 15:14:48 -0600 Subject: [PATCH 211/354] drivers: xds110: Add support of alternate XDS110 configurations The XDS110 supports alternate configurations, each of which has a unique vid/pid: 0451/bef3 -- Standard (legacy) configuration 0451/bef4 -- Drag-n-Drop configuration 1cbe/02a5 -- CMSIS-DAP 2.0 on BULK interface configuration It's not important to OpenOCD what the differences are except that OpenOCD needs to know how to connect using the different vid/pids and, in the case of the last one, use a different interface for the debug connection. Updated the XDS110 source to search for all possible configurations, and updated the udev rules file to enable user access to the alternate configuraitons. For the curious, you can download the latest XDS emupack from software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds_software_package_download.html Install to an empty directory, and documentation for the XDS110 is located in the .../ccs_base/common/uscif/xds110 of the installation. Updated for comments in code review. Changed const variable names to lower case. Reworked interface/endpoint setting to use arrays suggestion. Change-Id: Icc9d11c6618f43d87ae8171c78ebf238800d3ac2 Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5494 Tested-by: jenkins Reviewed-by: Antonio Borneo --- contrib/60-openocd.rules | 2 ++ src/jtag/drivers/xds110.c | 75 +++++++++++++++++++++++++++------------ 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/contrib/60-openocd.rules b/contrib/60-openocd.rules index ac574bb14..990412752 100644 --- a/contrib/60-openocd.rules +++ b/contrib/60-openocd.rules @@ -139,6 +139,8 @@ ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="660", GROUP="plugdev", # TI XDS110 Debug Probe (Launchpads and Standalone) ATTRS{idVendor}=="0451", ATTRS{idProduct}=="bef3", MODE="660", GROUP="plugdev", TAG+="uaccess" +ATTRS{idVendor}=="0451", ATTRS{idProduct}=="bef4", MODE="660", GROUP="plugdev", TAG+="uaccess" +ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="02a5", MODE="660", GROUP="plugdev", TAG+="uaccess" # TI Tiva-based ICDI and XDS110 probes in DFU mode ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00ff", MODE="660", GROUP="plugdev", TAG+="uaccess" diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index 9ca200e79..8a832adf0 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -66,15 +66,6 @@ #endif #define MAX_RESULT_QUEUE (MAX_DATA_BLOCK / 4) -/*************************************************************************** - * USB Connection Endpoints * - ***************************************************************************/ - -/* Bulk endpoints used by the XDS110 debug interface */ -#define INTERFACE_DEBUG (2) -#define ENDPOINT_DEBUG_IN (3 | LIBUSB_ENDPOINT_IN) -#define ENDPOINT_DEBUG_OUT (2 | LIBUSB_ENDPOINT_OUT) - /*************************************************************************** * XDS110 Firmware API Definitions * ***************************************************************************/ @@ -227,6 +218,13 @@ struct xds110_info { unsigned char read_payload[USB_PAYLOAD_SIZE]; unsigned char write_packet[3]; unsigned char write_payload[USB_PAYLOAD_SIZE]; + /* Device vid/pid */ + uint16_t vid; + uint16_t pid; + /* Debug interface */ + uint8_t interface; + uint8_t endpoint_in; + uint8_t endpoint_out; /* Status flags */ bool is_connected; bool is_cmapi_connected; @@ -259,6 +257,11 @@ struct xds110_info { static struct xds110_info xds110 = { .ctx = NULL, .dev = NULL, + .vid = 0, + .pid = 0, + .interface = 0, + .endpoint_in = 0, + .endpoint_out = 0, .is_connected = false, .is_cmapi_connected = false, .is_cmapi_acquired = false, @@ -320,12 +323,20 @@ static bool usb_connect(void) struct libusb_device_descriptor desc; - uint16_t vid = 0x0451; - uint16_t pid = 0xbef3; + /* The vid/pids of possible XDS110 configurations */ + uint16_t vids[] = { 0x0451, 0x0451, 0x1cbe }; + uint16_t pids[] = { 0xbef3, 0xbef4, 0x02a5 }; + /* Corresponding interface and endpoint numbers for configurations */ + uint8_t interfaces[] = { 2, 2, 0 }; + uint8_t endpoints_in[] = { 3, 3, 1 }; + uint8_t endpoints_out[] = { 2, 2, 1 }; + ssize_t count = 0; ssize_t i = 0; int result = 0; bool found = false; + uint32_t device = 0; + bool match = false; /* Initialize libusb context */ result = libusb_init(&ctx); @@ -342,13 +353,21 @@ static bool usb_connect(void) if (0 == result) { /* Scan through list of devices for any XDS110s */ for (i = 0; i < count; i++) { - /* Check for device VID/PID match */ + /* Check for device vid/pid match */ libusb_get_device_descriptor(list[i], &desc); - if (desc.idVendor == vid && desc.idProduct == pid) { + match = false; + for (device = 0; device < sizeof(vids)/sizeof(vids[0]); device++) { + if (desc.idVendor == vids[device] && + desc.idProduct == pids[device]) { + match = true; + break; + } + } + if (match) { result = libusb_open(list[i], &dev); if (0 == result) { - const int MAX_DATA = 256; - unsigned char data[MAX_DATA + 1]; + const int max_data = 256; + unsigned char data[max_data + 1]; *data = '\0'; /* May be the requested device if serial number matches */ @@ -359,7 +378,7 @@ static bool usb_connect(void) } else { /* Get the device's serial number string */ result = libusb_get_string_descriptor_ascii(dev, - desc.iSerialNumber, data, MAX_DATA); + desc.iSerialNumber, data, max_data); if (0 < result && 0 == strcmp((char *)data, (char *)xds110.serial)) { found = true; @@ -387,6 +406,15 @@ static bool usb_connect(void) } if (found) { + /* Save the vid/pid of the device we're using */ + xds110.vid = vids[device]; + xds110.pid = pids[device]; + + /* Save the debug interface and endpoints for the device */ + xds110.interface = interfaces[device]; + xds110.endpoint_in = endpoints_in[device] | LIBUSB_ENDPOINT_IN; + xds110.endpoint_out = endpoints_out[device] | LIBUSB_ENDPOINT_OUT; + /* Save the context and device handles */ xds110.ctx = ctx; xds110.dev = dev; @@ -395,7 +423,7 @@ static bool usb_connect(void) (void)libusb_set_auto_detach_kernel_driver(dev, 1); /* Claim the debug interface on the XDS110 */ - result = libusb_claim_interface(dev, INTERFACE_DEBUG); + result = libusb_claim_interface(dev, xds110.interface); } else { /* Couldn't find an XDS110, flag the error */ result = -1; @@ -405,7 +433,7 @@ static bool usb_connect(void) if (0 != result) { if (NULL != dev) { /* Release the debug and data interface on the XDS110 */ - (void)libusb_release_interface(dev, INTERFACE_DEBUG); + (void)libusb_release_interface(dev, xds110.interface); libusb_close(dev); } if (NULL != ctx) @@ -427,7 +455,7 @@ static void usb_disconnect(void) { if (NULL != xds110.dev) { /* Release the debug and data interface on the XDS110 */ - (void)libusb_release_interface(xds110.dev, INTERFACE_DEBUG); + (void)libusb_release_interface(xds110.dev, xds110.interface); libusb_close(xds110.dev); xds110.dev = NULL; } @@ -451,7 +479,7 @@ static bool usb_read(unsigned char *buffer, int size, int *bytes_read, if (0 == timeout) timeout = DEFAULT_TIMEOUT; - result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_IN, buffer, size, + result = libusb_bulk_transfer(xds110.dev, xds110.endpoint_in, buffer, size, bytes_read, timeout); return (0 == result) ? true : false; @@ -466,13 +494,13 @@ static bool usb_write(unsigned char *buffer, int size, int *written) if (NULL == xds110.dev || NULL == buffer) return false; - result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer, + result = libusb_bulk_transfer(xds110.dev, xds110.endpoint_out, buffer, size, &bytes_written, 0); while (LIBUSB_ERROR_PIPE == result && retries < 3) { /* Try clearing the pipe stall and retry transfer */ - libusb_clear_halt(xds110.dev, ENDPOINT_DEBUG_OUT); - result = libusb_bulk_transfer(xds110.dev, ENDPOINT_DEBUG_OUT, buffer, + libusb_clear_halt(xds110.dev, xds110.endpoint_out); + result = libusb_bulk_transfer(xds110.dev, xds110.endpoint_out, buffer, size, &bytes_written, 0); retries++; } @@ -1360,6 +1388,7 @@ static void xds110_show_info(void) { uint32_t firmware = xds110.firmware; + LOG_INFO("XDS110: vid/pid = %04x/%04x", xds110.vid, xds110.pid); LOG_INFO("XDS110: firmware version = %d.%d.%d.%d", (((firmware >> 28) & 0xf) * 10) + ((firmware >> 24) & 0xf), (((firmware >> 20) & 0xf) * 10) + ((firmware >> 16) & 0xf), From 4d7c48fb80cb65d53ad3bcd57182ffb79b61e5f3 Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Mon, 2 Mar 2020 14:04:24 -0600 Subject: [PATCH 212/354] tcl/target: Enable using vectreset for CC3320SF targets On CC32xx family of devices, sysrequest is disabled, and vectreset is blocked by the boot loader (stops in a while(1) statement). srst reset can leave the target in a state that prevents debug. This change enables using vectreset on SF variants by moving the PC to the start of the user application in internal flash. This allows for a more reliable reset, but with two caveats: 1) This only works for the SF variant with internal flash. 2) This only resets the CPU and not any peripherals. Tested on CC3220SF rev B Launchpad in both SWD and JTAG modes. Confirmed proper behavior of reset, reset init, reset halt, and reset run commands. Update: reworked per comment in code review. Re-tested with CC3220SF Launchpad as both CC3220SF and as CC32xx board to confirm reset behavior as expected. Update: Added adapter srst delay 1100 line to the CC3200 LaunchXL configuration file. Change-Id: Ibc042d785c846c2223ae55b8f2410b75ed2df354 Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5489 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/board/ti_cc3200_launchxl.cfg | 1 + tcl/board/ti_cc32xx_launchpad.cfg | 3 +++ tcl/target/ti_cc3220sf.cfg | 28 ++++++++++++++++++++++++++++ tcl/target/ti_cc32xx.cfg | 3 --- 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/tcl/board/ti_cc3200_launchxl.cfg b/tcl/board/ti_cc3200_launchxl.cfg index 34f9bffb8..b37b406ad 100644 --- a/tcl/board/ti_cc3200_launchxl.cfg +++ b/tcl/board/ti_cc3200_launchxl.cfg @@ -18,3 +18,4 @@ set WORKAREASIZE 0x40000 source [find target/ti_cc32xx.cfg] reset_config srst_only +adapter srst delay 1100 diff --git a/tcl/board/ti_cc32xx_launchpad.cfg b/tcl/board/ti_cc32xx_launchpad.cfg index 1df461a93..d0f2a831c 100644 --- a/tcl/board/ti_cc32xx_launchpad.cfg +++ b/tcl/board/ti_cc32xx_launchpad.cfg @@ -5,3 +5,6 @@ source [find interface/xds110.cfg] adapter speed 8500 transport select swd source [find target/ti_cc32xx.cfg] + +reset_config srst_only +adapter srst delay 1100 diff --git a/tcl/target/ti_cc3220sf.cfg b/tcl/target/ti_cc3220sf.cfg index f7d9bfe17..3e758e6ab 100644 --- a/tcl/target/ti_cc3220sf.cfg +++ b/tcl/target/ti_cc3220sf.cfg @@ -10,3 +10,31 @@ source [find target/ti_cc32xx.cfg] set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME + +# +# On CC32xx family of devices, sysreqreset is disabled, and vectreset is +# blocked by the boot loader (stops in a while(1) statement). srst reset can +# leave the target in a state that prevents debug. The following uses the +# soft_reset_halt command to reset and halt the target. Then the PC and stack +# are initialized from internal flash. This allows for a more reliable reset, +# but with two caveats: it only works for the SF variant that has internal +# flash, and it only resets the CPU and not any peripherals. +# + +proc ocd_process_reset_inner { MODE } { + + soft_reset_halt + + # Intialize MSP, PSP, and PC from vector table at flash 0x01000800 + mem2array boot 32 0x01000800 2 + + reg msp $boot(0) + reg psp $boot(0) + reg pc $boot(1) + + if { 0 == [string compare $MODE run ] } { + resume + } + + cc32xx.cpu invoke-event reset-end +} diff --git a/tcl/target/ti_cc32xx.cfg b/tcl/target/ti_cc32xx.cfg index 6f91d3fd3..e3e3ebc92 100644 --- a/tcl/target/ti_cc32xx.cfg +++ b/tcl/target/ti_cc32xx.cfg @@ -59,6 +59,3 @@ if { [info exists WORKAREASIZE] } { } $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 - -reset_config srst_only -adapter srst delay 1100 From b7c13323e702c7aa1d05d952708d1e408c47fae1 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 8 Mar 2020 16:40:05 +0100 Subject: [PATCH 213/354] doc: fix texinfo files attributes on Windows While installing git on Windows, the user is prompted by a dialog "Configuring the line ending conversions" to select the value for the git property "core.autocrlf". The default choice proposed by the installer is "Checkout Windows-style, commit Unix-style line endings", that corresponds to "core.autocrlf=true". Even if the dialog provides technical explanation of the different choices, most users will blindly accept the default proposal. With "core.autocrlf=true" git will convert to DOS mode all the text files during "clone" (so can be edited by any crap Windows tool) and convert back to UNIX mode during "push" operation. While this is safe enough for C and TCL files, it breaks the texinfo files. The trailing '@' character used for command continuation in https://www.gnu.org/software/texinfo/manual/texinfo/html_node/Def-Cmd-Continuation-Lines.html does not accept being followed by CR+LF (DOS mode), generating a build error. Same error can be replicated on Linux by passing the file doc/openocd.texi through "unix2dos" command. Tentative to fix this has already been proposed in http://openocd.zylin.com/5294 http://openocd.zylin.com/5413 by breaking the command continuation syntax, which is a no go. The correct fix would require to force/suggest all the Windows users to get rid of the crap DOS mode, but this could have side effects. To workaround the issue, add a .gitattributes file in the doc folder, specifying a local conversion attribute for the files .txt and .texi in the doc folder and overriding the eventual incorrect global value of "core.autocrlf" selected during installation. The local attribute "text eol=lf" is equivalent to the global one "core.autocrlf=input". Change-Id: I468a8f8125b6bc4628fce6c66eb082824ba3413f Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5499 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Tomas Vanek --- doc/.gitattributes | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 doc/.gitattributes diff --git a/doc/.gitattributes b/doc/.gitattributes new file mode 100644 index 000000000..dcf6d037c --- /dev/null +++ b/doc/.gitattributes @@ -0,0 +1,3 @@ +# Avoid DOS conversion of texinfo files during git clone +*.texi text eol=lf +*.txt text eol=lf From 85dc63011378c0a8112f99e3a02fa971f96bbc05 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 6 Mar 2020 10:30:25 +0100 Subject: [PATCH 214/354] jtag: fix command "adapter [de]assert" with dap direct The commit fafe6dfc9cd8 ("adapter: add command "adapter [de]assert srst|trst [[de]assert srst|trst]"") was proposed in gerrit well before commit a61ec3c1d73d ("adi_v5_dapdirect: add support for adapter drivers that provide DAP API") get merged, so it didn't include a complete support for dap direct. The merge upstream of the two commits lacks the support by command "adapter [de]assert" for dap direct Let command command "adapter [de]assert" handle dap direct. Change-Id: I1a69f8ee877c8fd57598ed4ad9d71da61d15457c Fixes: commit fafe6dfc9cd8 ("adapter: add command "adapter [de]assert srst|trst [[de]assert srst|trst]"") Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5515 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index c5011e522..001523365 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -2021,7 +2021,8 @@ int adapter_resets(int trst, int srst) /* adapters without trst signal will eventually use tlr sequence */ jtag_add_reset(trst, srst); return ERROR_OK; - } else if (transport_is_swd() || transport_is_hla()) { + } else if (transport_is_swd() || transport_is_hla() || + transport_is_dapdirect_swd() || transport_is_dapdirect_jtag()) { if (trst == TRST_ASSERT) { LOG_ERROR("transport %s has no trst signal", get_current_transport()->name); From a708b6d25ec72c6de57ff42bdc6c0b4d52a69388 Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Tue, 5 Nov 2019 16:37:43 +0100 Subject: [PATCH 215/354] avrf.c: Use extended addressing for flash > 0x20000 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current method used for flash addressing uses 16 bit. Every access to flash is 16 bit wide. With 16 address bits one can address 0x10000 unique locations á 16 bits thats 0x20000 bytes. For flashes bigger than that avrs have an extended addressing with more than 16 address bits. This is now implemented and used for flashs larger than 0x20000 bytes. Change-Id: Id8b6337dde3830fb3c56b9042872e040bb67c12d Signed-off-by: Lars Pöschel Reviewed-on: http://openocd.zylin.com/5502 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/avrf.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c index 178567e6b..aa8645909 100644 --- a/src/flash/nor/avrf.c +++ b/src/flash/nor/avrf.c @@ -142,6 +142,7 @@ static int avr_jtagprg_chiperase(struct avr_common *avr) } static int avr_jtagprg_writeflashpage(struct avr_common *avr, + const bool ext_addressing, const uint8_t *page_buf, uint32_t buf_size, uint32_t addr, @@ -152,6 +153,13 @@ static int avr_jtagprg_writeflashpage(struct avr_common *avr, avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2310, AVR_JTAG_REG_ProgrammingCommand_Len); + /* load extended high byte */ + if (ext_addressing) + avr_jtag_senddat(avr->jtag_info.tap, + NULL, + 0x0b00 | ((addr >> 17) & 0xFF), + AVR_JTAG_REG_ProgrammingCommand_Len); + /* load addr high byte */ avr_jtag_senddat(avr->jtag_info.tap, NULL, @@ -238,6 +246,7 @@ static int avrf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t o struct target *target = bank->target; struct avr_common *avr = target->arch_info; uint32_t cur_size, cur_buffer_size, page_size; + bool ext_addressing; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -258,6 +267,11 @@ static int avrf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t o if (ERROR_OK != avr_jtagprg_enterprogmode(avr)) return ERROR_FAIL; + if (bank->size > 0x20000) + ext_addressing = true; + else + ext_addressing = false; + cur_size = 0; while (count > 0) { if (count > page_size) @@ -265,6 +279,7 @@ static int avrf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t o else cur_buffer_size = count; avr_jtagprg_writeflashpage(avr, + ext_addressing, buffer + cur_size, cur_buffer_size, offset + cur_size, From d9ffe75e257aa4005dd34603860e45c57b1765b6 Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Tue, 5 Nov 2019 16:39:48 +0100 Subject: [PATCH 216/354] avrf.c: Add ATmega256RFR2 to known flash list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the ATmega256RFR2 to the list of know devices for flashing. Change-Id: Ib24a508762aaa84ba08ba37409db2ae674b46288 Signed-off-by: Lars Pöschel Reviewed-on: http://openocd.zylin.com/5504 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/avrf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c index aa8645909..de8c563c6 100644 --- a/src/flash/nor/avrf.c +++ b/src/flash/nor/avrf.c @@ -67,6 +67,7 @@ static const struct avrf_type avft_chips_info[] = { */ {"atmega128", 0x9702, 256, 512, 8, 512}, {"atmega128rfa1", 0xa701, 128, 512, 8, 512}, + {"atmega256rfr2", 0xa802, 256, 1024, 8, 1024}, {"at90can128", 0x9781, 256, 512, 8, 512}, {"at90usb128", 0x9782, 256, 512, 8, 512}, {"atmega164p", 0x940a, 128, 128, 4, 128}, From 9960e805b389b3ff46801b336772ab31d35a31a6 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 14 Feb 2019 16:11:44 +0100 Subject: [PATCH 217/354] target: Add function to remove all breakpoints Change-Id: I4718926844a2c8bcfd78d7a8792f6ded293548ef Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/4915 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- src/target/breakpoints.c | 30 +++++++++++++++++++++++++++++- src/target/breakpoints.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index 7ad194256..c060c7cde 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -332,6 +332,18 @@ static int breakpoint_remove_internal(struct target *target, target_addr_t addre return 0; } } + +static void breakpoint_remove_all_internal(struct target *target) +{ + struct breakpoint *breakpoint = target->breakpoints; + + while (breakpoint) { + struct breakpoint *tmp = breakpoint; + breakpoint = breakpoint->next; + breakpoint_free(target, tmp); + } +} + void breakpoint_remove(struct target *target, target_addr_t address) { int found = 0; @@ -350,7 +362,23 @@ void breakpoint_remove(struct target *target, target_addr_t address) breakpoint_remove_internal(target, address); } -void breakpoint_clear_target_internal(struct target *target) +void breakpoint_remove_all(struct target *target) +{ + if (target->smp) { + struct target_list *head; + struct target *curr; + head = target->head; + while (head != (struct target_list *)NULL) { + curr = head->target; + breakpoint_remove_all_internal(curr); + head = head->next; + } + } else { + breakpoint_remove_all_internal(target); + } +} + +static void breakpoint_clear_target_internal(struct target *target) { LOG_DEBUG("Delete all breakpoints for target: %s", target_name(target)); diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h index 51bd05abd..20faf4e6c 100644 --- a/src/target/breakpoints.h +++ b/src/target/breakpoints.h @@ -63,6 +63,7 @@ int context_breakpoint_add(struct target *target, int hybrid_breakpoint_add(struct target *target, target_addr_t address, uint32_t asid, uint32_t length, enum breakpoint_type type); void breakpoint_remove(struct target *target, target_addr_t address); +void breakpoint_remove_all(struct target *target); struct breakpoint *breakpoint_find(struct target *target, target_addr_t address); From 5ceae0eef4c4cdcb1c54807a93144b2700593d44 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 14 Feb 2019 16:12:22 +0100 Subject: [PATCH 218/354] target: Add possibility to remove all breakpoints Change-Id: I46acd57956846d66bef974e0538452462b197cd0 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/4916 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- doc/openocd.texi | 4 ++-- src/target/target.c | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 4665092d1..e60d26939 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -8173,8 +8173,8 @@ in which case it will be a hardware breakpoint. for similar mechanisms that do not consume hardware breakpoints.) @end deffn -@deffn Command {rbp} address -Remove the breakpoint at @var{address}. +@deffn Command {rbp} @option{all} | address +Remove the breakpoint at @var{address} or all breakpoints. @end deffn @deffn Command {rwp} address diff --git a/src/target/target.c b/src/target/target.c index b77400c1f..50dd1488f 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -3829,11 +3829,16 @@ COMMAND_HANDLER(handle_rbp_command) if (CMD_ARGC != 1) return ERROR_COMMAND_SYNTAX_ERROR; - target_addr_t addr; - COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr); - struct target *target = get_current_target(CMD_CTX); - breakpoint_remove(target, addr); + + if (!strcmp(CMD_ARGV[0], "all")) { + breakpoint_remove_all(target); + } else { + target_addr_t addr; + COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr); + + breakpoint_remove(target, addr); + } return ERROR_OK; } @@ -6318,7 +6323,7 @@ static const struct command_registration target_exec_command_handlers[] = { .handler = handle_rbp_command, .mode = COMMAND_EXEC, .help = "remove breakpoint", - .usage = "address", + .usage = "'all' | address", }, { .name = "wp", From f00070edaf8fbe7e49c44845c440086d55288f28 Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Thu, 12 Mar 2020 19:05:37 +0300 Subject: [PATCH 219/354] target/arc_cmd: Improve argument checks for commands Add more argument check for "add-reg" command. Changes since first revision: -Removed arguments limitation(50 maximum) for "arc_set_reg_exists". Changes: 25.03: Removed inconsistency in "add-reg" function. Actually "-type" option is optional and if it is not set, register type is "int". Change-Id: Ia21e6baf4fbda162f7811cd0fe305fc86ddafcfd Signed-off-by: Evgeniy Didin Reviewed-on: http://openocd.zylin.com/5523 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Oleksij Rempel --- src/target/arc_cmd.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c index 3475762f4..a8c3bb43a 100644 --- a/src/target/arc_cmd.c +++ b/src/target/arc_cmd.c @@ -678,13 +678,15 @@ static int jim_arc_add_reg(Jim_Interp *interp, int argc, Jim_Obj * const *argv) int type_name_len = strlen(type_name); int e = ERROR_OK; - /* At least we need to specify 4 parameters: name, number, type and gdb_feature, - * which means there should be 8 arguments */ - if (goi.argc < 8) { + /* At least we need to specify 4 parameters: name, number and gdb_feature, + * which means there should be 6 arguments. Also there can be additional paramters + * "-type ", "-g" and "-core" or "-bcr" which makes maximum 10 parameters. */ + if (goi.argc < 6 || goi.argc > 10) { free_reg_desc(reg); Jim_SetResultFormatted(goi.interp, - "Should be at least 8 argnuments: -name " - "-num -type -feature ."); + "Should be at least 6 argnuments and not greater than 10: " + " -name -num -feature " + " [-type ] [-core|-bcr] [-g]."); return JIM_ERR; } From af69f5ad0bb0cd38ad3163a8a3f3602d751c5d6d Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 2 Mar 2020 13:58:07 +0100 Subject: [PATCH 220/354] doc: fix OpenRISC target documentation OpenRISC correct target name is 'or1k' not 'openrisc' http://openocd.zylin.com/3096 introduced a conflict between 'openrisc' and 'ls1_sap' documentations Change-Id: Iedebbf9809300e1272334c5b63d0b31a41062282 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5485 Tested-by: jenkins Reviewed-by: Esben Haabendal Reviewed-by: Oleksij Rempel --- doc/openocd.texi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index e60d26939..b5692e653 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4434,10 +4434,10 @@ The current implementation supports eSi-32xx cores. @item @code{mips_m4k} -- a MIPS core @item @code{xscale} -- this is actually an architecture, not a CPU type. It is based on the ARMv5 architecture. -@item @code{openrisc} -- this is an OpenRISC 1000 core. -The current implementation supports three JTAG TAP cores: @item @code{ls1_sap} -- this is the SAP on NXP LS102x CPUs, allowing access to physical memory addresses independently of CPU cores. +@item @code{or1k} -- this is an OpenRISC 1000 core. +The current implementation supports three JTAG TAP cores: @itemize @minus @item @code{OpenCores TAP} (See: @url{http://opencores.org/project@comma{}jtag}) @item @code{Altera Virtual JTAG TAP} (See: @url{http://www.altera.com/literature/ug/ug_virtualjtag.pdf}) From 8f221f32bc7f55b25641f527e4a05a5f0ced89bf Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 2 Mar 2020 14:20:27 +0100 Subject: [PATCH 221/354] doc: enhance target types description target types are sorted alphabetically minor changes for some precision: - cortex_a : it's an ARMv7-A core - cortex_m : besides the ARMv7-M it support the v6-M and v8-M cores Change-Id: I37ade2392fe3948fba4156a2831bbd8739fa9993 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5486 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Oleksij Rempel --- doc/openocd.texi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index b5692e653..55df358f0 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4410,6 +4410,7 @@ Lists all supported target types. At this writing, the supported CPU types are: @itemize @bullet +@item @code{aarch64} -- this is an ARMv8-A core with an MMU @item @code{arm11} -- this is a generation of ARMv6 cores @item @code{arm720t} -- this is an ARMv4 core with an MMU @item @code{arm7tdmi} -- this is an ARMv4 core @@ -4419,10 +4420,9 @@ At this writing, the supported CPU types are: @item @code{arm9tdmi} -- this is an ARMv4 core @item @code{avr} -- implements Atmel's 8-bit AVR instruction set. (Support for this is preliminary and incomplete.) -@item @code{cortex_a} -- this is an ARMv7 core with an MMU -@item @code{cortex_m} -- this is an ARMv7 core, supporting only the -compact Thumb2 instruction set. -@item @code{aarch64} -- this is an ARMv8-A core with an MMU +@item @code{cortex_a} -- this is an ARMv7-A core with an MMU +@item @code{cortex_m} -- this is an ARMv7-M core, supporting only the +compact Thumb2 instruction set. Supports also ARMv6-M and ARMv8-M cores @item @code{dragonite} -- resembles arm966e @item @code{dsp563xx} -- implements Freescale's 24-bit DSP. (Support for this is still incomplete.) @@ -4430,12 +4430,10 @@ compact Thumb2 instruction set. The current implementation supports eSi-32xx cores. @item @code{fa526} -- resembles arm920 (w/o Thumb) @item @code{feroceon} -- resembles arm926 -@item @code{mem_ap} -- this is an ARM debug infrastructure Access Port without a CPU, through which bus read and write cycles can be generated; it may be useful for working with non-CPU hardware behind an AP or during development of support for new CPUs. -@item @code{mips_m4k} -- a MIPS core -@item @code{xscale} -- this is actually an architecture, -not a CPU type. It is based on the ARMv5 architecture. @item @code{ls1_sap} -- this is the SAP on NXP LS102x CPUs, allowing access to physical memory addresses independently of CPU cores. +@item @code{mem_ap} -- this is an ARM debug infrastructure Access Port without a CPU, through which bus read and write cycles can be generated; it may be useful for working with non-CPU hardware behind an AP or during development of support for new CPUs. +@item @code{mips_m4k} -- a MIPS core @item @code{or1k} -- this is an OpenRISC 1000 core. The current implementation supports three JTAG TAP cores: @itemize @minus @@ -4448,6 +4446,8 @@ And two debug interfaces cores: @item @code{Advanced debug interface} (See: @url{http://opencores.org/project@comma{}adv_debug_sys}) @item @code{SoC Debug Interface} (See: @url{http://opencores.org/project@comma{}dbg_interface}) @end itemize +@item @code{xscale} -- this is actually an architecture, +not a CPU type. It is based on the ARMv5 architecture. @end itemize @end deffn From d6541a811dc32beafbb388a01289366f1f31fc00 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 2 Mar 2020 15:28:04 +0100 Subject: [PATCH 222/354] doc: add missing target types missing target types are arm946e, avr32_ap7k, cortex_r4, dsp5680xx, hla_target, mips_mips64, nds32_v2, nds32_v3, nds32_v3m, quark_d20xx, quark_x10xx, riscv, stm8 and testee Change-Id: I38f6ed78ee88c09add4b779cd409ebb1e219304f Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5487 Reviewed-by: Antonio Borneo Tested-by: jenkins Reviewed-by: Tim Newsome Reviewed-by: Oleksij Rempel --- doc/openocd.texi | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 55df358f0..250db326f 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4410,30 +4410,39 @@ Lists all supported target types. At this writing, the supported CPU types are: @itemize @bullet -@item @code{aarch64} -- this is an ARMv8-A core with an MMU -@item @code{arm11} -- this is a generation of ARMv6 cores -@item @code{arm720t} -- this is an ARMv4 core with an MMU -@item @code{arm7tdmi} -- this is an ARMv4 core -@item @code{arm920t} -- this is an ARMv4 core with an MMU -@item @code{arm926ejs} -- this is an ARMv5 core with an MMU -@item @code{arm966e} -- this is an ARMv5 core -@item @code{arm9tdmi} -- this is an ARMv4 core +@item @code{aarch64} -- this is an ARMv8-A core with an MMU. +@item @code{arm11} -- this is a generation of ARMv6 cores. +@item @code{arm720t} -- this is an ARMv4 core with an MMU. +@item @code{arm7tdmi} -- this is an ARMv4 core. +@item @code{arm920t} -- this is an ARMv4 core with an MMU. +@item @code{arm926ejs} -- this is an ARMv5 core with an MMU. +@item @code{arm946e} -- this is an ARMv5 core with an MMU. +@item @code{arm966e} -- this is an ARMv5 core. +@item @code{arm9tdmi} -- this is an ARMv4 core. @item @code{avr} -- implements Atmel's 8-bit AVR instruction set. (Support for this is preliminary and incomplete.) -@item @code{cortex_a} -- this is an ARMv7-A core with an MMU +@item @code{avr32_ap7k} -- this an AVR32 core. +@item @code{cortex_a} -- this is an ARMv7-A core with an MMU. @item @code{cortex_m} -- this is an ARMv7-M core, supporting only the compact Thumb2 instruction set. Supports also ARMv6-M and ARMv8-M cores -@item @code{dragonite} -- resembles arm966e +@item @code{cortex_r4} -- this is an ARMv7-R core. +@item @code{dragonite} -- resembles arm966e. @item @code{dsp563xx} -- implements Freescale's 24-bit DSP. (Support for this is still incomplete.) +@item @code{dsp5680xx} -- implements Freescale's 5680x DSP. @item @code{esirisc} -- this is an EnSilica eSi-RISC core. The current implementation supports eSi-32xx cores. -@item @code{fa526} -- resembles arm920 (w/o Thumb) -@item @code{feroceon} -- resembles arm926 +@item @code{fa526} -- resembles arm920 (w/o Thumb). +@item @code{feroceon} -- resembles arm926. +@item @code{hla_target} -- a Cortex-M alternative to work with HL adapters like ST-Link. @item @code{ls1_sap} -- this is the SAP on NXP LS102x CPUs, allowing access to physical memory addresses independently of CPU cores. @item @code{mem_ap} -- this is an ARM debug infrastructure Access Port without a CPU, through which bus read and write cycles can be generated; it may be useful for working with non-CPU hardware behind an AP or during development of support for new CPUs. -@item @code{mips_m4k} -- a MIPS core +@item @code{mips_m4k} -- a MIPS core. +@item @code{mips_mips64} -- a MIPS64 core. +@item @code{nds32_v2} -- this is an Andes NDS32 v2 core. +@item @code{nds32_v3} -- this is an Andes NDS32 v3 core. +@item @code{nds32_v3m} -- this is an Andes NDS32 v3m core. @item @code{or1k} -- this is an OpenRISC 1000 core. The current implementation supports three JTAG TAP cores: @itemize @minus @@ -4446,6 +4455,11 @@ And two debug interfaces cores: @item @code{Advanced debug interface} (See: @url{http://opencores.org/project@comma{}adv_debug_sys}) @item @code{SoC Debug Interface} (See: @url{http://opencores.org/project@comma{}dbg_interface}) @end itemize +@item @code{quark_d20xx} -- an Intel Quark D20xx core. +@item @code{quark_x10xx} -- an Intel Quark X10xx core. +@item @code{riscv} -- a RISC-V core. +@item @code{stm8} -- implements an STM8 core. +@item @code{testee} -- a dummy target for cases without a real CPU, e.g. CPLD. @item @code{xscale} -- this is actually an architecture, not a CPU type. It is based on the ARMv5 architecture. @end itemize From 0690361abc3ae91171e83f34bddcf92bf78e02d3 Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Tue, 24 Mar 2020 16:46:59 -0500 Subject: [PATCH 223/354] flash/nor: Change missing protect_check message from WARN to Info. Change the current message when a flash driver does not implement the protect_check function to LOG_INFO() from LOG_WARNING(). The user is still notified that the procedure isn't available, but changes the tone to indicate this is expected with this flash driver and not something that necessarily is a problem to fix. Change-Id: If8a2e86a23c852d562346ca36734e5d02df4a851 Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5539 Reviewed-by: Antonio Borneo Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/tcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 40105b43f..30c5d4c80 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -109,7 +109,7 @@ COMMAND_HANDLER(handle_flash_info_command) return retval; } if (retval == ERROR_FLASH_OPER_UNSUPPORTED) - LOG_WARNING("Flash protection check is not implemented."); + LOG_INFO("Flash protection check is not implemented."); command_print(CMD, "#%d : %s at " TARGET_ADDR_FMT ", size 0x%8.8" PRIx32 From fa329f2852cf13584d38c6f8eb6250c5c976907f Mon Sep 17 00:00:00 2001 From: Roman Elshin Date: Sun, 22 Mar 2020 12:37:00 +0300 Subject: [PATCH 224/354] cmsis_dap_usb: Light up the leds while connected Tested with Keil ULINK2 CMSIS-DAP. Change-Id: I331224d23412bed8b2dea25abacbf9096ddd18b1 Signed-off-by: Roman Elshin Reviewed-on: http://openocd.zylin.com/5385 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/cmsis_dap_usb.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c index 3d2693c0a..289737754 100644 --- a/src/jtag/drivers/cmsis_dap_usb.c +++ b/src/jtag/drivers/cmsis_dap_usb.c @@ -509,15 +509,15 @@ static int cmsis_dap_cmd_DAP_Info(uint8_t info, uint8_t **data) return ERROR_OK; } -static int cmsis_dap_cmd_DAP_LED(uint8_t leds) +static int cmsis_dap_cmd_DAP_LED(uint8_t led, uint8_t state) { int retval; uint8_t *buffer = cmsis_dap_handle->packet_buffer; buffer[0] = 0; /* report number */ buffer[1] = CMD_DAP_LED; - buffer[2] = 0x00; - buffer[3] = leds; + buffer[2] = led; + buffer[3] = state; retval = cmsis_dap_usb_xfer(cmsis_dap_handle, 4); if (retval != ERROR_OK || buffer[1] != 0x00) { @@ -1086,8 +1086,12 @@ static int cmsis_dap_init(void) if (retval != ERROR_OK) return ERROR_FAIL; } + /* Both LEDs on */ + retval = cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_ON); + if (retval != ERROR_OK) + return ERROR_FAIL; - retval = cmsis_dap_cmd_DAP_LED(0x03); /* Both LEDs on */ + retval = cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_ON); if (retval != ERROR_OK) return ERROR_FAIL; @@ -1102,9 +1106,6 @@ static int cmsis_dap_init(void) LOG_INFO("Connecting under reset"); } } - - cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */ - LOG_INFO("CMSIS-DAP: Interface ready"); return ERROR_OK; @@ -1119,7 +1120,9 @@ static int cmsis_dap_swd_init(void) static int cmsis_dap_quit(void) { cmsis_dap_cmd_DAP_Disconnect(); - cmsis_dap_cmd_DAP_LED(0x00); /* Both LEDs off */ + /* Both LEDs off */ + cmsis_dap_cmd_DAP_LED(LED_ID_RUN, LED_OFF); + cmsis_dap_cmd_DAP_LED(LED_ID_CONNECT, LED_OFF); cmsis_dap_usb_close(cmsis_dap_handle); From 1c16d76c00cd48ac99daeae41cb59fa7d078fa48 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Fri, 7 Feb 2020 20:13:10 +0100 Subject: [PATCH 225/354] flash/stm32f1x: fix maximum flash size for some devices For STM32F0xxx, according to RM0360 Rev 4 and RM0091 Rev 9, the accurate flash sizes are in RM0360, Table 4 and 5 DEV_ID=0x440 => F030x8 => 64K (64 * 1K) F05xxx => idem DEV_ID=0x442 => F030xC => 256K (128 * 2K) F09xxx => idem DEV_ID=0x444 => F030x4 => 16K (16 * 1K) F030x6 => 32K (32 * 1K) DEV_ID=0x445 => F070x6 => 32K (32 * 1K) F04xxx => idem DEV_ID=0x448 => F070xB => 128K (64 * 2K) For STM32 F100xx HD VL (0x428), max_flash_size_kb is 512 (was 128) refer to RM0041 Rev5: Table 5. Flash module organization (high-density value line devices) => (256 page of 2 Kbytes each) Change-Id: I4ead13093f8f4b8ec900482ee049a6fc83dcc664 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5444 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/stm32f1x.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index 7d5a8f0a2..37dcafd87 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -714,8 +714,6 @@ static int stm32x_probe(struct flash_bank *bank) /* set page size, protection granularity and max flash size depending on family */ switch (device_id & 0xfff) { case 0x440: /* stm32f05x */ - case 0x444: /* stm32f03x */ - case 0x445: /* stm32f04x */ page_size = 1024; stm32x_info->ppage_size = 4; max_flash_size_in_kb = 64; @@ -724,7 +722,25 @@ static int stm32x_probe(struct flash_bank *bank) stm32x_info->default_rdp = 0xAA; stm32x_info->can_load_options = true; break; + case 0x444: /* stm32f03x */ + case 0x445: /* stm32f04x */ + page_size = 1024; + stm32x_info->ppage_size = 4; + max_flash_size_in_kb = 32; + stm32x_info->user_data_offset = 16; + stm32x_info->option_offset = 6; + stm32x_info->default_rdp = 0xAA; + stm32x_info->can_load_options = true; + break; case 0x448: /* stm32f07x */ + page_size = 2048; + stm32x_info->ppage_size = 4; + max_flash_size_in_kb = 128; + stm32x_info->user_data_offset = 16; + stm32x_info->option_offset = 6; + stm32x_info->default_rdp = 0xAA; + stm32x_info->can_load_options = true; + break; case 0x442: /* stm32f09x */ page_size = 2048; stm32x_info->ppage_size = 4; @@ -768,7 +784,7 @@ static int stm32x_probe(struct flash_bank *bank) case 0x428: /* stm32f100xx high-density value line */ page_size = 2048; stm32x_info->ppage_size = 4; - max_flash_size_in_kb = 128; + max_flash_size_in_kb = 512; break; case 0x422: /* stm32f302/3xb/c */ page_size = 2048; From af82b97834cfba60144894b79244cf421ff88359 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Fri, 21 Feb 2020 15:26:10 +0100 Subject: [PATCH 226/354] flash/nor/cfi: Minor code cleanups Change-Id: I2d45fcc5b9d232db66218aab5fef3add5830bcd7 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5463 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/cfi.c | 75 ++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 45 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 224f1749a..80a0a33ee 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -100,9 +100,8 @@ static const struct cfi_fixup cfi_0001_fixups[] = { static void cfi_fixup(struct flash_bank *bank, const struct cfi_fixup *fixups) { struct cfi_flash_bank *cfi_info = bank->driver_priv; - const struct cfi_fixup *f; - for (f = fixups; f->fixup; f++) { + for (const struct cfi_fixup *f = fixups; f->fixup; f++) { if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi_info->manufacturer)) && ((f->id == CFI_ID_ANY) || (f->id == cfi_info->device_id))) f->fixup(bank, f->param); @@ -154,20 +153,19 @@ int cfi_target_read_memory(struct flash_bank *bank, target_addr_t addr, static void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf) { - int i; struct cfi_flash_bank *cfi_info = bank->driver_priv; /* clear whole buffer, to ensure bits that exceed the bus_width * are set to zero */ - for (i = 0; i < CFI_MAX_BUS_WIDTH; i++) + for (size_t i = 0; i < CFI_MAX_BUS_WIDTH; i++) cmd_buf[i] = 0; if (cfi_info->endianness == TARGET_LITTLE_ENDIAN) { - for (i = bank->bus_width; i > 0; i--) + for (int i = bank->bus_width; i > 0; i--) *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd; } else { - for (i = 1; i <= bank->bus_width; i++) + for (int i = 1; i <= bank->bus_width; i++) *cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd; } } @@ -211,7 +209,6 @@ static int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint { struct cfi_flash_bank *cfi_info = bank->driver_priv; uint8_t data[CFI_MAX_BUS_WIDTH]; - int i; int retval; retval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset), @@ -220,13 +217,13 @@ static int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint return retval; if (cfi_info->endianness == TARGET_LITTLE_ENDIAN) { - for (i = 0; i < bank->bus_width / bank->chip_width; i++) + for (int i = 0; i < bank->bus_width / bank->chip_width; i++) data[0] |= data[i]; *val = data[0]; } else { uint8_t value = 0; - for (i = 0; i < bank->bus_width / bank->chip_width; i++) + for (int i = 0; i < bank->bus_width / bank->chip_width; i++) value |= data[bank->bus_width - 1 - i]; *val = value; @@ -241,8 +238,7 @@ static int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, u int retval; if (cfi_info->x16_as_x8) { - uint8_t i; - for (i = 0; i < 2; i++) { + for (uint8_t i = 0; i < 2; i++) { retval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset + i), 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) @@ -270,8 +266,7 @@ static int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, u int retval; if (cfi_info->x16_as_x8) { - uint8_t i; - for (i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 4; i++) { retval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset + i), 1, &data[i * bank->bus_width]); if (retval != ERROR_OK) @@ -841,7 +836,7 @@ int cfi_flash_bank_cmd(struct flash_bank *bank, unsigned int argc, const char ** } cfi_info = malloc(sizeof(struct cfi_flash_bank)); - cfi_info->probed = 0; + cfi_info->probed = false; cfi_info->erase_region_info = NULL; cfi_info->pri_ext = NULL; bank->driver_priv = cfi_info; @@ -886,11 +881,10 @@ static int cfi_intel_erase(struct flash_bank *bank, int first, int last) { int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; - int i; cfi_intel_clear_status_register(bank); - for (i = first; i <= last; i++) { + for (int i = first; i <= last; i++) { retval = cfi_send_command(bank, 0x20, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; @@ -942,9 +936,8 @@ static int cfi_spansion_erase(struct flash_bank *bank, int first, int last) int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - int i; - for (i = first; i <= last; i++) { + for (int i = first; i <= last; i++) { retval = cfi_spansion_unlock_seq(bank); if (retval != ERROR_OK) return retval; @@ -1014,7 +1007,6 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext; int retry = 0; - int i; /* if the device supports neither legacy lock/unlock (bit 3) nor * instant individual block locking (bit 5). @@ -1026,7 +1018,7 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la cfi_intel_clear_status_register(bank); - for (i = first; i <= last; i++) { + for (int i = first; i <= last; i++) { retval = cfi_send_command(bank, 0x60, cfi_flash_address(bank, i, 0x0)); if (retval != ERROR_OK) return retval; @@ -1097,7 +1089,7 @@ static int cfi_intel_protect(struct flash_bank *bank, int set, int first, int la * 3. re-protect what should be protected. * */ - for (i = 0; i < bank->num_sectors; i++) { + for (int i = 0; i < bank->num_sectors; i++) { if (bank->sectors[i].is_protected == 1) { cfi_intel_clear_status_register(bank); @@ -2276,7 +2268,6 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u uint32_t read_p; int align; /* number of unaligned bytes */ uint8_t current_word[CFI_MAX_BUS_WIDTH]; - int i; int retval; LOG_DEBUG("reading buffer of %i byte at 0x%8.8x", @@ -2305,7 +2296,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u return retval; /* take only bytes we need */ - for (i = align; (i < bank->bus_width) && (count > 0); i++, count--) + for (int i = align; (i < bank->bus_width) && (count > 0); i++, count--) *buffer++ = current_word[i]; read_p += bank->bus_width; @@ -2331,7 +2322,7 @@ static int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, u return retval; /* take only bytes we need */ - for (i = 0; (i < bank->bus_width) && (count > 0); i++, count--) + for (int i = 0; (i < bank->bus_width) && (count > 0); i++, count--) *buffer++ = current_word[i]; } @@ -2349,7 +2340,6 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of *programmed */ uint8_t *swapped_buffer = NULL; const uint8_t *real_buffer = NULL; - int i; int retval; if (bank->target->state != TARGET_HALTED) { @@ -2375,7 +2365,7 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of return retval; /* replace only bytes that must be written */ - for (i = align; + for (int i = align; (i < bank->bus_width) && (count > 0); i++, count--) if (cfi_info->data_swap) @@ -2441,12 +2431,12 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of /* fall back to memory writes */ while (count >= (uint32_t)bank->bus_width) { - int fallback; + bool fallback; if ((write_p & 0xff) == 0) { LOG_INFO("Programming at 0x%08" PRIx32 ", count 0x%08" PRIx32 " bytes remaining", write_p, count); } - fallback = 1; + fallback = true; if ((bufferwsize > 0) && (count >= buffersize) && !(write_p & buffermask)) { retval = cfi_write_words(bank, buffer, bufferwsize, write_p); @@ -2454,13 +2444,13 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of buffer += buffersize; write_p += buffersize; count -= buffersize; - fallback = 0; + fallback = false; } else if (retval != ERROR_FLASH_OPER_UNSUPPORTED) return retval; } /* try the slow way? */ if (fallback) { - for (i = 0; i < bank->bus_width; i++) + for (int i = 0; i < bank->bus_width; i++) current_word[i] = *buffer++; retval = cfi_write_word(bank, current_word, write_p); @@ -2495,7 +2485,7 @@ static int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t of return retval; /* replace only bytes that must be written */ - for (i = 0; (i < bank->bus_width) && (count > 0); i++, count--) + for (int i = 0; (i < bank->bus_width) && (count > 0); i++, count--) if (cfi_info->data_swap) /* data bytes are swapped (reverse endianness) */ current_word[bank->bus_width - i] = *buffer++; @@ -2522,7 +2512,6 @@ static void cfi_fixup_reversed_erase_regions(struct flash_bank *bank, const void static void cfi_fixup_0002_erase_regions(struct flash_bank *bank, const void *param) { - int i; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; (void) param; @@ -2530,7 +2519,7 @@ static void cfi_fixup_0002_erase_regions(struct flash_bank *bank, const void *pa if ((pri_ext->_reversed_geometry) || (pri_ext->TopBottom == 3)) { LOG_DEBUG("swapping reversed erase region information on cmdset 0002 device"); - for (i = 0; i < cfi_info->num_erase_regions / 2; i++) { + for (unsigned int i = 0; i < cfi_info->num_erase_regions / 2; i++) { int j = (cfi_info->num_erase_regions - 1) - i; uint32_t swap; @@ -2598,7 +2587,6 @@ int cfi_probe(struct flash_bank *bank) struct cfi_flash_bank *cfi_info = bank->driver_priv; struct target *target = bank->target; int num_sectors = 0; - int i; int sector = 0; uint32_t unlock1 = 0x555; uint32_t unlock2 = 0x2aa; @@ -2610,7 +2598,7 @@ int cfi_probe(struct flash_bank *bank) return ERROR_TARGET_NOT_HALTED; } - cfi_info->probed = 0; + cfi_info->probed = false; cfi_info->num_erase_regions = 0; if (bank->sectors) { free(bank->sectors); @@ -2782,7 +2770,7 @@ int cfi_probe(struct flash_bank *bank) if (cfi_info->num_erase_regions) { cfi_info->erase_region_info = malloc(sizeof(*cfi_info->erase_region_info) * cfi_info->num_erase_regions); - for (i = 0; i < cfi_info->num_erase_regions; i++) { + for (unsigned int i = 0; i < cfi_info->num_erase_regions; i++) { retval = cfi_query_u32(bank, 0, 0x2d + (4 * i), @@ -2897,15 +2885,14 @@ int cfi_probe(struct flash_bank *bank) } else { uint32_t offset = 0; - for (i = 0; i < cfi_info->num_erase_regions; i++) + for (unsigned int i = 0; i < cfi_info->num_erase_regions; i++) num_sectors += (cfi_info->erase_region_info[i] & 0xffff) + 1; bank->num_sectors = num_sectors; bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); - for (i = 0; i < cfi_info->num_erase_regions; i++) { - uint32_t j; - for (j = 0; j < (cfi_info->erase_region_info[i] & 0xffff) + 1; j++) { + for (unsigned int i = 0; i < cfi_info->num_erase_regions; i++) { + for (uint32_t j = 0; j < (cfi_info->erase_region_info[i] & 0xffff) + 1; j++) { bank->sectors[sector].offset = offset; bank->sectors[sector].size = ((cfi_info->erase_region_info[i] >> 16) * 256) @@ -2924,7 +2911,7 @@ int cfi_probe(struct flash_bank *bank) } } - cfi_info->probed = 1; + cfi_info->probed = true; return ERROR_OK; } @@ -2942,7 +2929,6 @@ static int cfi_intel_protect_check(struct flash_bank *bank) int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext; - int i; /* check if block lock bits are supported on this device */ if (!(pri_ext->blk_status_reg_mask & 0x1)) @@ -2952,7 +2938,7 @@ static int cfi_intel_protect_check(struct flash_bank *bank) if (retval != ERROR_OK) return retval; - for (i = 0; i < bank->num_sectors; i++) { + for (int i = 0; i < bank->num_sectors; i++) { uint8_t block_status; retval = cfi_get_u8(bank, i, 0x2, &block_status); if (retval != ERROR_OK) @@ -2972,7 +2958,6 @@ static int cfi_spansion_protect_check(struct flash_bank *bank) int retval; struct cfi_flash_bank *cfi_info = bank->driver_priv; struct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext; - int i; retval = cfi_spansion_unlock_seq(bank); if (retval != ERROR_OK) @@ -2982,7 +2967,7 @@ static int cfi_spansion_protect_check(struct flash_bank *bank) if (retval != ERROR_OK) return retval; - for (i = 0; i < bank->num_sectors; i++) { + for (int i = 0; i < bank->num_sectors; i++) { uint8_t block_status; retval = cfi_get_u8(bank, i, 0x2, &block_status); if (retval != ERROR_OK) From 4ce4aa752b638d8eb39864d1ad498bde139f5233 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Fri, 13 Mar 2020 11:49:25 +0100 Subject: [PATCH 227/354] armv8: log the register name which we failed to read or write when openocd fails to read armv8 register, the user is not informed which register has caused the error. for example, in AArch32 state ESR_EL3 read/write is not supported, thus armv8_dpm_read_current_registers is always failing without mentioning which register has caused the error. Change-Id: I24c5abbda9fac24fb77a01777ed15261aeaaf800 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5516 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/armv8_dpm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c index 081eed21b..5be52726c 100644 --- a/src/target/armv8_dpm.c +++ b/src/target/armv8_dpm.c @@ -681,6 +681,10 @@ static int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) LOG_DEBUG("READ: %s, hvalue=%16.8llx", r->name, (unsigned long long) hvalue); } } + + if (retval != ERROR_OK) + LOG_ERROR("Failed to read %s register", r->name); + return retval; } @@ -720,6 +724,9 @@ static int dpmv8_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) } } + if (retval != ERROR_OK) + LOG_ERROR("Failed to write %s register", r->name); + return retval; } From 56ff1ecddb4302ba53b6eed3581b0ca2a4e23d78 Mon Sep 17 00:00:00 2001 From: Laurent LEMELE Date: Wed, 12 Feb 2020 22:22:54 +0100 Subject: [PATCH 228/354] stlink: fix speed setting in dap mode stlink accepts a set of values for "adapter speed". Fix the api khz() to return one of the allowed speed values. Change-Id: Iac640b6f76935891ca25ac168cab3809707f19d9 Signed-off-by: Laurent LEMELE Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5464 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 6ab979f1c..d630c1962 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -3705,7 +3705,12 @@ static int stlink_dap_speed(int speed) /** */ static int stlink_dap_khz(int khz, int *jtag_speed) { - *jtag_speed = khz; + if (khz == 0) { + LOG_ERROR("RCLK not supported"); + return ERROR_FAIL; + } + + *jtag_speed = stlink_speed(stlink_dap_handle, khz, true); return ERROR_OK; } From d14eac569c761b3026d32b4977edb371fa6b8fbe Mon Sep 17 00:00:00 2001 From: Laurent LEMELE Date: Fri, 14 Feb 2020 17:01:04 +0100 Subject: [PATCH 229/354] stlink: remove 18 MHz jtag freq for stlink v2 While stlink v2 allows setting the jtag clock frequency till a max of 18 MHz, the firmware seams unstable and not properly working. Remove the entry for 18 MHz, at least until a fix get available. Change-Id: I503e1b6a5709b5fbf1f1147fd3b5f34a0c5ee98c Signed-off-by: Laurent LEMELE Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5465 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index d630c1962..3f9ce37a9 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -347,7 +347,6 @@ static const struct speed_map stlink_khz_to_speed_map_swd[] = { /* JTAG clock speed */ static const struct speed_map stlink_khz_to_speed_map_jtag[] = { - {18000, 2}, {9000, 4}, {4500, 8}, {2250, 16}, From eb427864e8b7f12fffe85327b03b9b9cdf397c1d Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Tue, 10 Mar 2020 15:11:43 -0500 Subject: [PATCH 230/354] tcl/target: Use vectreset for CC13xx/CC26xx targets. nSRST and sysreqreset are both broken for these targets. Upon a hard reset, the target disables the TDO/TDI pins and the ICEPick router will remove the target's TAP from the scan chain. The scripts to do these tasks are run, but then OpenOCD throws the reset again breaking the debug connection. Until that issue can be resolved, vectreset is the only reset that works without breaking the debug connection. Update: original patch didn't have the correct reset command. Change-Id: If7c985b703c87399a13364609d370d6222f4a66c Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5511 Tested-by: jenkins Reviewed-by: Tomas Vanek --- tcl/target/ti_cc26x0.cfg | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tcl/target/ti_cc26x0.cfg b/tcl/target/ti_cc26x0.cfg index 8d8a0df4e..f95d7b2fc 100644 --- a/tcl/target/ti_cc26x0.cfg +++ b/tcl/target/ti_cc26x0.cfg @@ -52,5 +52,4 @@ $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME -reset_config srst_only -adapter srst delay 100 +cortex_m reset_config vectreset From 0a804222da63c5f849efa23b019a59e2dea76842 Mon Sep 17 00:00:00 2001 From: Sasha Kozaruk Date: Thu, 19 Mar 2020 18:53:24 -0700 Subject: [PATCH 231/354] flash/stm32h7x: Use proper flash regs base for bank 1 On stm32h747 writing/erasing bank 1 didn't work. It was because the flash register base was always set for bank 0. Tested on STM32H747I-DISCO board. Change-Id: I7e8c43ecdda9dc70b114905f5ec6a6753ca29d82 Signed-off-by: Sasha Kozaruk Reviewed-on: http://openocd.zylin.com/5534 Reviewed-by: Christopher Head Tested-by: jenkins --- src/flash/nor/stm32h7x.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index 1e2b35159..7b6fdb39c 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -118,7 +118,6 @@ struct stm32h7x_part_info { uint16_t max_flash_size_kb; bool has_dual_bank; uint16_t max_bank_size_kb; /* Used when has_dual_bank is true */ - uint32_t flash_regs_base; /* Flash controller registers location */ uint32_t fsize_addr; /* Location of FSIZE register */ uint32_t wps_group_size; /* write protection group sectors' count */ uint32_t wps_mask; @@ -175,7 +174,6 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .max_flash_size_kb = 2048, .max_bank_size_kb = 1024, .has_dual_bank = true, - .flash_regs_base = FLASH_REG_BASE_B0, .fsize_addr = 0x1FF1E880, .wps_group_size = 1, .wps_mask = 0xFF, @@ -191,7 +189,6 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .max_flash_size_kb = 2048, .max_bank_size_kb = 1024, .has_dual_bank = true, - .flash_regs_base = FLASH_REG_BASE_B0, .fsize_addr = 0x08FFF80C, .wps_group_size = 4, .wps_mask = 0xFFFFFFFF, @@ -763,8 +760,16 @@ static int stm32x_probe(struct flash_bank *bank) LOG_INFO("Device: %s", stm32x_info->part_info->device_str); } - /* update the address of controller from data base */ - stm32x_info->flash_regs_base = stm32x_info->part_info->flash_regs_base; + /* update the address of controller */ + if (bank->base == FLASH_BANK0_ADDRESS) + stm32x_info->flash_regs_base = FLASH_REG_BASE_B0; + else if (bank->base == FLASH_BANK1_ADDRESS) + stm32x_info->flash_regs_base = FLASH_REG_BASE_B1; + else { + LOG_WARNING("Flash register base not defined for bank %d", bank->bank_number); + return ERROR_FAIL; + } + LOG_DEBUG("flash_regs_base: 0x%" PRIx32, stm32x_info->flash_regs_base); /* get flash size from target */ retval = target_read_u16(target, stm32x_info->part_info->fsize_addr, &flash_size_in_kb); From 25efc150694042b349b8df1ff7c41f16955c5288 Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Wed, 1 Apr 2020 11:58:20 +0200 Subject: [PATCH 232/354] target: added events TARGET_EVENT_STEP_START and _END Events TARGET_EVENT_STEP_START and TARGET_EVENT_STEP_END have been added - analogous to already existing events TARGET_EVENT_RESUME_*. This is an example of a concrete use case where having these events is important: In RISC-V processors without Debug Program Buffer, OpenOCD cannot execute fence/fence.i when resuming or single- stepping. With these events implemented, the user can instead provide custom operations to achieve that same effect prior to resuming the processor. Change-Id: I786348ff08940759d99b0f24e9e0ed5a44581094 Signed-off-by: Jan Matyas Reviewed-on: http://openocd.zylin.com/5551 Tested-by: jenkins Reviewed-by: Tim Newsome --- doc/openocd.texi | 4 ++++ src/target/target.c | 16 ++++++++++++++-- src/target/target.h | 2 ++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 250db326f..0c58a682c 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4924,6 +4924,10 @@ when reset disables PLLs needed to use a fast clock. @* After all targets have resumed @item @b{resumed} @* Target has resumed +@item @b{step-start} +@* Before a target is single-stepped +@item @b{step-end} +@* After single-step has completed @item @b{trace-config} @* After target hardware trace configuration was changed @end itemize diff --git a/src/target/target.c b/src/target/target.c index 50dd1488f..24fa416f8 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -205,6 +205,8 @@ static const Jim_Nvp nvp_target_event[] = { { .value = TARGET_EVENT_RESUMED, .name = "resumed" }, { .value = TARGET_EVENT_RESUME_START, .name = "resume-start" }, { .value = TARGET_EVENT_RESUME_END, .name = "resume-end" }, + { .value = TARGET_EVENT_STEP_START, .name = "step-start" }, + { .value = TARGET_EVENT_STEP_END, .name = "step-end" }, { .name = "gdb-start", .value = TARGET_EVENT_GDB_START }, { .name = "gdb-end", .value = TARGET_EVENT_GDB_END }, @@ -1256,7 +1258,17 @@ bool target_supports_gdb_connection(struct target *target) int target_step(struct target *target, int current, target_addr_t address, int handle_breakpoints) { - return target->type->step(target, current, address, handle_breakpoints); + int retval; + + target_call_event_callbacks(target, TARGET_EVENT_STEP_START); + + retval = target->type->step(target, current, address, handle_breakpoints); + if (retval != ERROR_OK) + return retval; + + target_call_event_callbacks(target, TARGET_EVENT_STEP_END); + + return retval; } int target_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info) @@ -3145,7 +3157,7 @@ COMMAND_HANDLER(handle_step_command) struct target *target = get_current_target(CMD_CTX); - return target->type->step(target, current_pc, addr, 1); + return target_step(target, current_pc, addr, 1); } void target_handle_md_output(struct command_invocation *cmd, diff --git a/src/target/target.h b/src/target/target.h index b954ec22d..ddeb00b57 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -258,6 +258,8 @@ enum target_event { TARGET_EVENT_RESUMED, /* target resumed to normal execution */ TARGET_EVENT_RESUME_START, TARGET_EVENT_RESUME_END, + TARGET_EVENT_STEP_START, + TARGET_EVENT_STEP_END, TARGET_EVENT_GDB_START, /* debugger started execution (step/run) */ TARGET_EVENT_GDB_END, /* debugger stopped execution (step/run) */ From 21b9a0e1e33f371026d6497ab3ce81ed9ea73db4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 10 Jan 2020 02:06:45 +0100 Subject: [PATCH 233/354] travis: Add .travis.yml Add basic Travis-CI .travis.yml, to let Travis CI run automated build tests. Change-Id: Iceae442c13f30b57842b300c0920108b614c75f7 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5414 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- .travis.yml | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..da6b94c3f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,91 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright Marek Vasut + +# OpenOCD on Travis CI - https://travis-ci.org/ + +sudo: required +dist: bionic + +arch: + - amd64 + - arm64 + - ppc64le + - s390x + +addons: + apt: + sources: + - sourceline: 'ppa:ubuntu-toolchain-r/test' + - sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main' + key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' + packages: + - libftdi-dev + - libhidapi-dev + - libjaylink-dev + +env: + - CC=gcc-9 + - CC=clang-9 + +language: c + +git: + depth: 1 + autocrlf: input + +script: + - $mingw64 ${CC} --version + - $mingw64 env + - $mingw64 ./bootstrap + - $mingw64 ./configure + - $mingw64 make + +before_install: + - |- + case $TRAVIS_OS_NAME in + linux) + sudo apt install ${CC} libusb-1.0-0-dev + ;; + osx) + brew install libtool automake libusb libusb-compat hidapi libftdi + ;; + windows) + [[ ! -f C:/tools/msys64/msys2_shell.cmd ]] && rm -rf C:/tools/msys64 + choco uninstall -y mingw + choco upgrade --no-progress -y msys2 + export msys2='cmd //C RefreshEnv.cmd ' + export msys2+='& set MSYS=winsymlinks:nativestrict ' + export msys2+='& C:\\tools\\msys64\\msys2_shell.cmd -defterm -no-start' + export mingw64="$msys2 -mingw64 -full-path -here -c \$\* --" + export msys2+=" -msys2 -c \$\* --" + $msys2 pacman --sync --noconfirm --needed mingw-w64-x86_64-toolchain autoconf autoconf-archive automake automake-wrapper binutils gcc gettext git libtool m4 make pkg-config tcl texinfo mingw-w64-x86_64-libusb mingw-w64-x86_64-libusb-compat-git mingw-w64-x86_64-libjaylink-git mingw-w64-x86_64-libftdi mingw-w64-x86_64-hidapi mingw-w64-x86_64-clang + ## FIXME: Also build for i686? + ## Install more MSYS2 packages from https://packages.msys2.org/base here + taskkill //IM gpg-agent.exe //F # https://travis-ci.community/t/4967 + export PATH=/C/tools/msys64/mingw64/bin:$PATH + export MAKE=mingw32-make # so that Autotools can find it + ;; + esac + +before_cache: +- |- + case $TRAVIS_OS_NAME in + windows) + # https://unix.stackexchange.com/a/137322/107554 + $msys2 pacman --sync --clean --noconfirm + ;; + esac + +cache: + directories: + - $HOME/AppData/Local/Temp/chocolatey + - /C/tools/msys64 + +matrix: + include: + - os: osx + env: + - CC=clang + - os: windows + env: + - CC=gcc From 27d04d42842b31a3eb83de965ba7f3dc0fac3142 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 29 Mar 2020 23:19:29 +0200 Subject: [PATCH 234/354] sysfsgpio: minor fix for bool types Return bool value in functions that return bool. Change return type to bool to function is_gpio_valid(). Change-Id: Ic2e62be737772b22e69881c034956549f659370b Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5552 Tested-by: jenkins Reviewed-by: Marc Schink --- src/jtag/drivers/sysfsgpio.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index bf33767c8..c398d5384 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -61,7 +61,7 @@ * * Assume here that there will be less than 10000 gpios on a system */ -static int is_gpio_valid(int gpio) +static bool is_gpio_valid(int gpio) { return gpio >= 0 && gpio < 10000; } @@ -603,23 +603,23 @@ static void cleanup_all_fds(void) static bool sysfsgpio_jtag_mode_possible(void) { if (!is_gpio_valid(tck_gpio)) - return 0; + return false; if (!is_gpio_valid(tms_gpio)) - return 0; + return false; if (!is_gpio_valid(tdi_gpio)) - return 0; + return false; if (!is_gpio_valid(tdo_gpio)) - return 0; - return 1; + return false; + return true; } static bool sysfsgpio_swd_mode_possible(void) { if (!is_gpio_valid(swclk_gpio)) - return 0; + return false; if (!is_gpio_valid(swdio_gpio)) - return 0; - return 1; + return false; + return true; } static int sysfsgpio_init(void) From 02903916dd004f03290bdf766e02ce73151f7d71 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 26 Mar 2020 23:35:08 +0100 Subject: [PATCH 235/354] flash/nor/nrf5: pass unsigned char to isalnum() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In newlib, the argument of isalnum() and the similar functions in ctype.h is checked to be either an int or an unsigned char. Using a normal (signed) char triggers a compile time warning warning: array subscript has type ‘char’ [-Wchar-subscripts] Rewrite the function to separate the internal unsigned char operations from the (signed) char parameter. Change-Id: I5f19115f0b2de2b5b35dc07ef4b58a96161268ee Signed-off-by: Antonio Borneo Reported-by: Åke Rehnman Fixes: 5da746fa09 ("flash/nor/nrf5: detect newer devices without HWID table") Reviewed-on: http://openocd.zylin.com/5545 Tested-by: jenkins Reviewed-by: Ake Rehnman --- src/flash/nor/nrf5.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 8422589b8..5bef8487c 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -570,10 +570,14 @@ static int nrf5_protect(struct flash_bank *bank, int set, int first, int last) static bool nrf5_info_variant_to_str(uint32_t variant, char *bf) { - h_u32_to_be((uint8_t *)bf, variant); - bf[4] = '\0'; - if (isalnum(bf[0]) && isalnum(bf[1]) && isalnum(bf[2]) && isalnum(bf[3])) + uint8_t b[4]; + + h_u32_to_be(b, variant); + if (isalnum(b[0]) && isalnum(b[1]) && isalnum(b[2]) && isalnum(b[3])) { + memcpy(bf, b, 4); + bf[4] = 0; return true; + } strcpy(bf, "xxxx"); return false; From cbbc56f7f7bef9e0e1cb8711576449c62fe31654 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 26 Mar 2020 15:16:52 +0100 Subject: [PATCH 236/354] stlink: remove only instance of useconds_t The usleep() function, and its associated useconds_t type specifier, has been obsoleted by POSIX.1-2008. OpenOCD has 28 call to usleep(), that should be migrated to the replacement nanosleep(), but due to the different prototype int nanosleep(const struct timespec *req, struct timespec *rem); this can take some effort. The type useconds_t is used in only one case, where it's used both as parameter of usleep() and as value passed to LOG_DEBUG(). Due to different implementation of useconds_t, there are cases that trigger a compile warning in LOG_DEBUG() when useconds_t is more than 32 bit. E.g. with unistd.h in MinGW 4.x, useconds_t is defined as unsigned long, thus being 32 or 64 bits depending on the target. Replace the only instance of useconds_t. Change-Id: I21724f8b06780abdb003a57222ff1d6840ff5419 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5544 Tested-by: jenkins Reviewed-by: Ake Rehnman --- src/jtag/drivers/stlink_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 3f9ce37a9..f4992daa6 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -834,7 +834,7 @@ static int stlink_cmd_allow_retry(void *handle, const uint8_t *buf, int size) res = stlink_usb_error_check(handle); if (res == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { - useconds_t delay_us = (1< Date: Wed, 12 Feb 2020 22:26:51 +0100 Subject: [PATCH 237/354] cortex_a: don't wait for target halted in deassert_reset() The tcl script src/target/startup.tcl has already the proper centralized support to wait for all targets to halt after the command "reset halt". The extra wait in cortex_a_deassert_reset() is not required. This extra wait is also an issue for multi-core support, because waiting for one core to halt can delay the halt request to the other cores. Replace the indirect call to cortex_a_halt(), that embeds the wait for halt, with a low-level halt sequence. The on-going work on the reset framework is compatible with this change; in fact it keeps in startup.tcl the wait for targets to halt, even if current code proposal for cortex_a simply removes the function cortex_a_deassert_reset(). Change-Id: Ic661c3791a29ba7d520e31f85a61f939a646feb5 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5472 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/target/cortex_a.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 729a173eb..f71b15524 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1703,6 +1703,7 @@ static int cortex_a_assert_reset(struct target *target) static int cortex_a_deassert_reset(struct target *target) { + struct armv7a_common *armv7a = target_to_armv7a(target); int retval; LOG_DEBUG(" "); @@ -1721,7 +1722,8 @@ static int cortex_a_deassert_reset(struct target *target) LOG_WARNING("%s: ran after reset and before halt ...", target_name(target)); if (target_was_examined(target)) { - retval = target_halt(target); + retval = mem_ap_write_atomic_u32(armv7a->debug_ap, + armv7a->debug_base + CPUDBG_DRCR, DRCR_HALT); if (retval != ERROR_OK) return retval; } else From 17ac52360fc27eed9f58506a102a32b653d4d48c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 10 Mar 2020 23:07:42 +0100 Subject: [PATCH 238/354] cortex_m: remove deprecation for soft_reset_halt The command "soft_reset_halt" is deprecated since mid 2013 with the commit 146dfe32956d ("cortex_m: deprecate soft_reset_halt"). Nevertheless it is still extremely useful with multicore chips where it allows to reset only one of the cores, option not available through asserting the chip-wide srst. It also get useful to handle the reset on some problematic chip, as in http://openocd.zylin.com/5489 Replace the warning about deprecation with a more light debug message. Change-Id: I52de6359475ba31014ae77e596a87fe88b252177 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5514 Tested-by: jenkins Reviewed-by: Edward Fewell Reviewed-by: Tarek BOCHKATI --- src/target/cortex_m.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 9a1f2b16f..af245dfc0 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -710,11 +710,11 @@ static int cortex_m_soft_reset_halt(struct target *target) uint32_t dcb_dhcsr = 0; int retval, timeout = 0; - /* soft_reset_halt is deprecated on cortex_m as the same functionality - * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset' - * As this reset only used VC_CORERESET it would only ever reset the cortex_m + /* on single cortex_m MCU soft_reset_halt should be avoided as same functionality + * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'. + * As this reset only uses VC_CORERESET it would only ever reset the cortex_m * core, not the peripherals */ - LOG_WARNING("soft_reset_halt is deprecated, please use 'reset halt' instead."); + LOG_DEBUG("soft_reset_halt is discouraged, please use 'reset halt' instead."); /* Set C_DEBUGEN */ retval = cortex_m_write_debug_halt_mask(target, 0, C_STEP | C_MASKINTS); From 16706256e43cfdf6eb6b66e98f12f7a77f142edb Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 16 Mar 2020 14:53:18 +0100 Subject: [PATCH 239/354] gdb_server: print the target associated to the gdb port While running OpenOCD on multi-target SoC, it's not immediate to detect which target is associated to each GDB port. The log only reports: Info : Listening on port 3333 for gdb connections and a verbose debug log is required to get such info. Promote to LOG_INFO() the existing debug message that already reports the association, obtaining for each port: Info : starting gdb server for stm32mp15x.cpu0 on 3333 Info : Listening on port 3333 for gdb connections Change-Id: I1bd75655a3449222c959e6e82f5e0f8f5acd908a Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5525 Tested-by: jenkins Reviewed-by: Jan Matyas Reviewed-by: Tarek BOCHKATI --- src/server/gdb_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 0ca4fa4ee..3f2632b03 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -3489,7 +3489,7 @@ static int gdb_target_start(struct target *target, const char *port) if (NULL == gdb_service) return -ENOMEM; - LOG_DEBUG("starting gdb server for %s on %s", target_name(target), port); + LOG_INFO("starting gdb server for %s on %s", target_name(target), port); gdb_service->target = target; gdb_service->core[0] = -1; From 263296e549455afa1484cf9dec75fc3014a83954 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 3 Feb 2020 10:02:54 +0100 Subject: [PATCH 240/354] jtag: flush queue after reset for drivers using old reset model Not all the jtag drivers have been migrated to the new reset model and for those only we need to flush the jtag queue to make the reset working with command 'adapter [de]assert ...'. Add a queue flush and a FIXME comment to remove both when all the drivers would be migrated. Change-Id: Ib6667f987b1be2bce492841040302e742dd1cad1 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5430 Tested-by: jenkins --- src/jtag/core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/jtag/core.c b/src/jtag/core.c index 001523365..2d0c84205 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -2020,6 +2020,11 @@ int adapter_resets(int trst, int srst) /* adapters without trst signal will eventually use tlr sequence */ jtag_add_reset(trst, srst); + /* + * The jtag queue is still used for reset by some adapter. Flush it! + * FIXME: To be removed when all adapter drivers will be updated! + */ + jtag_execute_queue(); return ERROR_OK; } else if (transport_is_swd() || transport_is_hla() || transport_is_dapdirect_swd() || transport_is_dapdirect_jtag()) { From 68e200c660aefe960e351452748f299c4a334474 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 30 Mar 2020 13:06:18 +0200 Subject: [PATCH 241/354] stlink: always use a valid endpoint In order to extend the driver to support stlink-server over TCP, we should always use a valid endpoint, as stlink-server is not permissive and do not accept the invalid STLINK_NULL_EP. STLINK_NULL_EP value was used for commands without an expected reply, this value could be replaced with a valid endpoint without any impact when the size is set to zero. Change-Id: I003ad364e03d3a10bc036772db86310d996cbe81 Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5455 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/stlink_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index f4992daa6..45bb5019f 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -55,7 +55,6 @@ #define STLINK_WRITE_TIMEOUT 1000 #define STLINK_READ_TIMEOUT 1000 -#define STLINK_NULL_EP 0 #define STLINK_RX_EP (1|ENDPOINT_IN) #define STLINK_TX_EP (2|ENDPOINT_OUT) #define STLINK_TRACE_EP (3|ENDPOINT_IN) @@ -1251,7 +1250,8 @@ static int stlink_usb_mode_leave(void *handle, enum stlink_mode type) assert(handle != NULL); - stlink_usb_init_buffer(handle, STLINK_NULL_EP, 0); + /* command with no reply, use a valid endpoint but zero size */ + stlink_usb_init_buffer(handle, h->rx_ep, 0); switch (type) { case STLINK_MODE_DEBUG_JTAG: @@ -1272,7 +1272,7 @@ static int stlink_usb_mode_leave(void *handle, enum stlink_mode type) return ERROR_FAIL; } - res = stlink_usb_xfer_noerrcheck(handle, 0, 0); + res = stlink_usb_xfer_noerrcheck(handle, h->databuf, 0); if (res != ERROR_OK) return res; From b9a30e089227db441afd300989b0befce21b7da3 Mon Sep 17 00:00:00 2001 From: Ake Rehnman Date: Sun, 29 Mar 2020 12:13:18 +0200 Subject: [PATCH 242/354] Entering SWIM mode on ST-LINK does not update swim status word. As a consequence of a previous failed SWIM command any subsequent attempts to enter SWIM mode fails. Change stlink_usb_mode_enter to use stlink_usb_xfer_noerrcheck instead. Change-Id: I5c6a1a8e68d3dc77ec37264880383366fa6a75d9 Signed-off-by: Ake Rehnman Reviewed-on: http://openocd.zylin.com/5547 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/stlink_usb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 45bb5019f..a905576c8 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -1230,9 +1230,8 @@ static int stlink_usb_mode_enter(void *handle, enum stlink_mode type) case STLINK_MODE_DEBUG_SWIM: h->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND; h->cmdbuf[h->cmdidx++] = STLINK_SWIM_ENTER; - /* no answer for this function... */ - rx_size = 0; - break; + /* swim enter does not return any response or status */ + return stlink_usb_xfer_noerrcheck(handle, h->databuf, 0); case STLINK_MODE_DFU: case STLINK_MODE_MASS: default: From ef6eb5691aaaa3b13dccfff4a180b745803ae10b Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 6 Apr 2020 13:49:17 +0100 Subject: [PATCH 243/354] server/gdb_server: set gdb_connection::ctrl_c type to bool Change-Id: I828b83b181f7a222ee2e6cb67eb337c6cd8712ac Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5566 Tested-by: jenkins Reviewed-by: Marc Schink --- src/server/gdb_server.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 3f2632b03..857cffd9c 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -71,7 +71,7 @@ struct gdb_connection { char buffer[GDB_BUFFER_SIZE + 1]; /* Extra byte for nul-termination */ char *buf_p; int buf_cnt; - int ctrl_c; + bool ctrl_c; enum target_state frontend_state; struct image *vflash_image; bool closed; @@ -444,7 +444,7 @@ static int gdb_put_packet_inner(struct connection *connection, log_remove_callback(gdb_log_callback, connection); LOG_WARNING("negative reply, retrying"); } else if (reply == 0x3) { - gdb_con->ctrl_c = 1; + gdb_con->ctrl_c = true; retval = gdb_get_char(connection, &reply); if (retval != ERROR_OK) return retval; @@ -649,7 +649,7 @@ static int gdb_get_packet_inner(struct connection *connection, LOG_WARNING("negative acknowledgment, but no packet pending"); break; case 0x3: - gdb_con->ctrl_c = 1; + gdb_con->ctrl_c = true; *len = 0; return ERROR_OK; default: @@ -785,7 +785,7 @@ static void gdb_signal_reply(struct target *target, struct connection *connectio sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), "T%2.2x%s%s", signal_var, stop_reason, current_thread); - gdb_connection->ctrl_c = 0; + gdb_connection->ctrl_c = false; } gdb_put_packet(connection, sig_reply, sig_reply_len); @@ -942,7 +942,7 @@ static int gdb_new_connection(struct connection *connection) /* initialize gdb connection information */ gdb_connection->buf_p = gdb_connection->buffer; gdb_connection->buf_cnt = 0; - gdb_connection->ctrl_c = 0; + gdb_connection->ctrl_c = false; gdb_connection->frontend_state = TARGET_HALTED; gdb_connection->vflash_image = NULL; gdb_connection->closed = false; @@ -3453,7 +3453,7 @@ static int gdb_input_inner(struct connection *connection) retval = target_poll(t); if (retval != ERROR_OK) target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); - gdb_con->ctrl_c = 0; + gdb_con->ctrl_c = false; } else { LOG_INFO("The target is not running when halt was requested, stopping GDB."); target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); From e7f9ad3932105928cb9aaf6041590be396243402 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 6 Apr 2020 13:41:36 +0100 Subject: [PATCH 244/354] server: set connection::input_pending type to bool Change-Id: Ifae8ac2761a7a8fa12732b71c2de456e7558bd2b Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5565 Tested-by: jenkins Reviewed-by: Marc Schink --- src/server/gdb_server.c | 8 ++++---- src/server/server.c | 2 +- src/server/server.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 857cffd9c..6f326fe24 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -277,9 +277,9 @@ static int gdb_get_char_inner(struct connection *connection, int *next_char) gdb_con->buf_cnt--; *next_char = *(gdb_con->buf_p++); if (gdb_con->buf_cnt > 0) - connection->input_pending = 1; + connection->input_pending = true; else - connection->input_pending = 0; + connection->input_pending = false; #ifdef _DEBUG_GDB_IO_ LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char); #endif @@ -302,9 +302,9 @@ static inline int gdb_get_char_fast(struct connection *connection, *next_char = **buf_p; (*buf_p)++; if (*buf_cnt > 0) - connection->input_pending = 1; + connection->input_pending = true; else - connection->input_pending = 0; + connection->input_pending = false; #ifdef _DEBUG_GDB_IO_ LOG_DEBUG("returned char '%c' (0x%2.2x)", *next_char, *next_char); diff --git a/src/server/server.c b/src/server/server.c index 8e641176a..f32a9c76f 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -76,7 +76,7 @@ static int add_connection(struct service *service, struct command_context *cmd_c memset(&c->sin, 0, sizeof(c->sin)); c->cmd_ctx = copy_command_context(cmd_ctx); c->service = service; - c->input_pending = 0; + c->input_pending = false; c->priv = NULL; c->next = NULL; diff --git a/src/server/server.h b/src/server/server.h index 96e0b48ef..ab9b72f90 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -49,7 +49,7 @@ struct connection { struct sockaddr_in sin; struct command_context *cmd_ctx; struct service *service; - int input_pending; + bool input_pending; void *priv; struct connection *next; }; From 10b39c3db020464aca14ed41e6453567e26277fa Mon Sep 17 00:00:00 2001 From: tscn92 Date: Mon, 6 Apr 2020 15:51:23 +0200 Subject: [PATCH 245/354] flash/nor/efm32: Chip support extension (EFM32GG12B Giant) For flash/nor/efm32 the EFM32GG12B Giant chip has been added to the efm32_family along with its respective series and msc_rebase. Testen on EFM32GG12B390F board Change-Id: Idd7dfa93f26ac22566aed1be28f30db678cc0a25 Signed-off-by: tscn92 Reviewed-on: http://openocd.zylin.com/5567 Tested-by: jenkins Reviewed-by: Marc Schink --- src/flash/nor/efm32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c index 479e0d475..9cdc32573 100644 --- a/src/flash/nor/efm32.c +++ b/src/flash/nor/efm32.c @@ -169,6 +169,7 @@ static const struct efm32_family_data efm32_families[] = { { 91, "EFM32JG13B Jade", .series = 1 }, { 100, "EFM32GG11B Giant", .series = 1, .msc_regbase = 0x40000000 }, { 103, "EFM32TG11B Tiny", .series = 1, .msc_regbase = 0x40000000 }, + { 106, "EFM32GG12B Giant", .series = 1, .msc_regbase = 0x40000000 }, { 120, "EZR32WG Wonder", .series = 0 }, { 121, "EZR32LG Leopard", .series = 0 }, { 122, "EZR32HG Happy", .series = 0, .page_size = 1024 }, From a1c51caafbac67df36dbecb27dd4b195730354b9 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sun, 5 Apr 2020 17:34:14 +0200 Subject: [PATCH 246/354] Revert "rtos/FreeRTOS: Fix FreeRTOS thread list reading" This reverts commit 6568d29cc1d0d94daafec5bdb73de7d4f17da257. The reverted change caused some tasks were missing in thread list. While on it add a comment explaining the relation of uxTopUsedPriority and configMAX_PRIORITIES, introduce config_max_priorities and change types to unsigned. Change-Id: I4371c8882470d13ee7360ef21b132c56ecb95af8 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5577 Tested-by: jenkins --- src/rtos/FreeRTOS.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c index 77c6e79d5..c45d9d645 100644 --- a/src/rtos/FreeRTOS.c +++ b/src/rtos/FreeRTOS.c @@ -157,7 +157,6 @@ static const struct symbols FreeRTOS_symbol_list[] = { static int FreeRTOS_update_threads(struct rtos *rtos) { - int i = 0; int retval; int tasks_found = 0; const struct FreeRTOS_params *param; @@ -245,32 +244,40 @@ static int FreeRTOS_update_threads(struct rtos *rtos) LOG_ERROR("FreeRTOS: uxTopUsedPriority is not defined, consult the OpenOCD manual for a work-around"); return ERROR_FAIL; } - int64_t max_used_priority = 0; + uint64_t top_used_priority = 0; + /* FIXME: endianess error on almost all target_read_buffer(), see also + * other rtoses */ retval = target_read_buffer(rtos->target, rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address, param->pointer_width, - (uint8_t *)&max_used_priority); + (uint8_t *)&top_used_priority); if (retval != ERROR_OK) return retval; - LOG_DEBUG("FreeRTOS: Read uxTopUsedPriority at 0x%" PRIx64 ", value %" PRId64 "\r\n", + LOG_DEBUG("FreeRTOS: Read uxTopUsedPriority at 0x%" PRIx64 ", value %" PRIu64 "\r\n", rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address, - max_used_priority); - if (max_used_priority > FREERTOS_MAX_PRIORITIES) { - LOG_ERROR("FreeRTOS maximum used priority is unreasonably big, not proceeding: %" PRId64 "", - max_used_priority); + top_used_priority); + if (top_used_priority > FREERTOS_MAX_PRIORITIES) { + LOG_ERROR("FreeRTOS top used priority is unreasonably big, not proceeding: %" PRIu64, + top_used_priority); return ERROR_FAIL; } + /* uxTopUsedPriority was defined as configMAX_PRIORITIES - 1 + * in old FreeRTOS versions (before V7.5.3) + * Use contrib/rtos-helpers/FreeRTOS-openocd.c to get compatible symbol + * in newer FreeRTOS versions. + * Here we restore the original configMAX_PRIORITIES value */ + unsigned int config_max_priorities = top_used_priority + 1; + symbol_address_t *list_of_lists = - malloc(sizeof(symbol_address_t) * - (max_used_priority + 5)); + malloc(sizeof(symbol_address_t) * (config_max_priorities + 5)); if (!list_of_lists) { - LOG_ERROR("Error allocating memory for %" PRId64 " priorities", max_used_priority); + LOG_ERROR("Error allocating memory for %u priorities", config_max_priorities); return ERROR_FAIL; } - int num_lists; - for (num_lists = 0; num_lists < max_used_priority; num_lists++) + unsigned int num_lists; + for (num_lists = 0; num_lists < config_max_priorities; num_lists++) list_of_lists[num_lists] = rtos->symbols[FreeRTOS_VAL_pxReadyTasksLists].address + num_lists * param->list_width; @@ -280,7 +287,7 @@ static int FreeRTOS_update_threads(struct rtos *rtos) list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xSuspendedTaskList].address; list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xTasksWaitingTermination].address; - for (i = 0; i < num_lists; i++) { + for (unsigned int i = 0; i < num_lists; i++) { if (list_of_lists[i] == 0) continue; @@ -295,7 +302,7 @@ static int FreeRTOS_update_threads(struct rtos *rtos) free(list_of_lists); return retval; } - LOG_DEBUG("FreeRTOS: Read thread count for list %d at 0x%" PRIx64 ", value %" PRId64 "\r\n", + LOG_DEBUG("FreeRTOS: Read thread count for list %u at 0x%" PRIx64 ", value %" PRId64 "\r\n", i, list_of_lists[i], list_thread_count); if (list_thread_count == 0) @@ -313,7 +320,7 @@ static int FreeRTOS_update_threads(struct rtos *rtos) free(list_of_lists); return retval; } - LOG_DEBUG("FreeRTOS: Read first item for list %d at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", + LOG_DEBUG("FreeRTOS: Read first item for list %u at 0x%" PRIx64 ", value 0x%" PRIx64 "\r\n", i, list_of_lists[i] + param->list_next_offset, list_elem_ptr); while ((list_thread_count > 0) && (list_elem_ptr != 0) && From 435e6101c68616f0555193d1113a27b926f2c50d Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Thu, 28 Nov 2019 08:34:01 +0300 Subject: [PATCH 247/354] Introduce ARCv2 tcl config files With this commit we add tcl files which describes ARCv2 architecture features and configure files for ARCv2 EMSK board. Changes since v1: -Moved from http://openocd.zylin.com/#/c/5332/4 into separate commit. Changes: 22.01.2020: -Removed "actionpoints" handling code in tcl/cpu/arc/v2.tcl because this capability is not supported yet. Changes: 17.03.2020: -Update Licence headers -Cleanup indents -Removed "reset halt" in boards .tcl -Updated adapter frequency commands Changes: 15.03.2020: -Removed "init" in the of boards .tcl Change-Id: I51bf620abe7b8e046e1dccc861a7d963965d3a42 Signed-off-by: Evgeniy Didin Cc: Alexey Brodkin Reviewed-on: http://openocd.zylin.com/5350 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/board/snps_em_sk.cfg | 22 +++ tcl/board/snps_em_sk_v1.cfg | 20 +++ tcl/board/snps_em_sk_v2.1.cfg | 23 +++ tcl/board/snps_em_sk_v2.2.cfg | 22 +++ tcl/cpu/arc/common.tcl | 40 +++++ tcl/cpu/arc/em.tcl | 32 ++++ tcl/cpu/arc/v2.tcl | 288 +++++++++++++++++++++++++++++++++ tcl/target/snps_em_sk_fpga.cfg | 34 ++++ 8 files changed, 481 insertions(+) create mode 100644 tcl/board/snps_em_sk.cfg create mode 100644 tcl/board/snps_em_sk_v1.cfg create mode 100644 tcl/board/snps_em_sk_v2.1.cfg create mode 100644 tcl/board/snps_em_sk_v2.2.cfg create mode 100644 tcl/cpu/arc/common.tcl create mode 100644 tcl/cpu/arc/em.tcl create mode 100644 tcl/cpu/arc/v2.tcl create mode 100644 tcl/target/snps_em_sk_fpga.cfg diff --git a/tcl/board/snps_em_sk.cfg b/tcl/board/snps_em_sk.cfg new file mode 100644 index 000000000..63c39a4d4 --- /dev/null +++ b/tcl/board/snps_em_sk.cfg @@ -0,0 +1,22 @@ +# Copyright (C) 2014-2016,2020 Synopsys, Inc. +# Anton Kolesov +# Didin Evgeniy +# +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Synopsys DesignWare ARC EM Starter Kit v2.x +# + +# Configure JTAG cable +# EM Starter Kit has built-in FT2232 chip, which is similiar to Digilent HS-1. +source [find interface/ftdi/digilent-hs1.cfg] + +# 5MHz seems to work good with all cores that might happen in 2.x +adapter speed 5000 + +# ARCs support only JTAG. +transport select jtag + +# Configure FPGA. This script supports both LX45 and LX150. +source [find target/snps_em_sk_fpga.cfg] diff --git a/tcl/board/snps_em_sk_v1.cfg b/tcl/board/snps_em_sk_v1.cfg new file mode 100644 index 000000000..2e9d6025e --- /dev/null +++ b/tcl/board/snps_em_sk_v1.cfg @@ -0,0 +1,20 @@ +# Copyright (C) 2014-2016,2020 Synopsys, Inc. +# Anton Kolesov +# Didin Evgeniy +# +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Synopsys DesignWare ARC EM Starter Kit v1.0 and v1.1 +# + +# Configure JTAG cable +# EM Starter Kit has built-in FT2232 chip, which is similiar to Digilent HS-1. +source [find interface/ftdi/digilent-hs1.cfg] +adapter speed 10000 + +# ARCs support only JTAG. +transport select jtag + +# Configure FPGA. This script supports both LX45 and LX150. +source [find target/snps_em_sk_fpga.cfg] diff --git a/tcl/board/snps_em_sk_v2.1.cfg b/tcl/board/snps_em_sk_v2.1.cfg new file mode 100644 index 000000000..5df8de571 --- /dev/null +++ b/tcl/board/snps_em_sk_v2.1.cfg @@ -0,0 +1,23 @@ +# Copyright (C) 2014-2016,2020 Synopsys, Inc. +# Anton Kolesov +# Didin Evgeniy +# +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Synopsys DesignWare ARC EM Starter Kit v2.1 +# + +# Configure JTAG cable +# EM Starter Kit has built-in FT2232 chip, which is similiar to Digilent HS-1. +source [find interface/ftdi/digilent-hs1.cfg] + +# JTAG 10MHz is too fast for EM7D FPU in EM SK 2.1 which has core frequency +# 20MHz. 7.5 MHz seems to work fine. +adapter speed 7500 + +# ARCs support only JTAG. +transport select jtag + +# Configure FPGA. This script supports both LX45 and LX150. +source [find target/snps_em_sk_fpga.cfg] diff --git a/tcl/board/snps_em_sk_v2.2.cfg b/tcl/board/snps_em_sk_v2.2.cfg new file mode 100644 index 000000000..7f3708e5c --- /dev/null +++ b/tcl/board/snps_em_sk_v2.2.cfg @@ -0,0 +1,22 @@ +# Copyright (C) 2016,2020 Synopsys, Inc. +# Anton Kolesov +# Didin Evgeniy +# +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Synopsys DesignWare ARC EM Starter Kit v2.2 +# + +# Configure JTAG cable +# EM Starter Kit has built-in FT2232 chip, which is similiar to Digilent HS-1. +source [find interface/ftdi/digilent-hs1.cfg] + +# EM11D reportedly requires 5 MHz. Other cores and board can work faster. +adapter speed 5000 + +# ARCs support only JTAG. +transport select jtag + +# Configure FPGA. This script supports both LX45 and LX150. +source [find target/snps_em_sk_fpga.cfg] diff --git a/tcl/cpu/arc/common.tcl b/tcl/cpu/arc/common.tcl new file mode 100644 index 000000000..e9a915717 --- /dev/null +++ b/tcl/cpu/arc/common.tcl @@ -0,0 +1,40 @@ +# Copyright (C) 2015, 2020 Synopsys, Inc. +# Anton Kolesov +# Didin Evgeniy +# +# SPDX-License-Identifier: GPL-2.0-or-later + +# Things common to all ARCs + +# It is assumed that target is already halted. +proc arc_common_reset { {target ""} } { + if { $target != "" } { + targets $target + } + + halt + + # 1. Interrupts are disabled (STATUS32.IE) + # 2. The status register flags are cleared. + # All fields, except the H bit, are set to 0 when the processor is Reset. + + arc jtag set-aux-reg 0xA 0x1 + + # 3. The loop count, loop start, and loop end registers are cleared. + arc jtag set-core-reg 60 0 + arc jtag set-aux-reg 0x2 0 + arc jtag set-aux-reg 0x3 0 + + # Program execution begins at the address referenced by the four byte reset + # vector located at the interrupt vector base address, which is the first + # entry (offset 0x00) in the vector table. + set int_vector_base [arc jtag get-aux-reg 0x25] + set start_pc "" + mem2array start_pc 32 $int_vector_base 1 + arc jtag set-aux-reg 0x6 $start_pc(0) + + # It is OK to do uncached writes - register cache will be invalidated by + # the reset_assert() function. +} + +# vim:expandtab: diff --git a/tcl/cpu/arc/em.tcl b/tcl/cpu/arc/em.tcl new file mode 100644 index 000000000..f0455bb74 --- /dev/null +++ b/tcl/cpu/arc/em.tcl @@ -0,0 +1,32 @@ +# Copyright (C) 2015, 2020 Synopsys, Inc. +# Anton Kolesov +# Didin Evgeniy +# +# SPDX-License-Identifier: GPL-2.0-or-later + +source [find cpu/arc/v2.tcl] + +proc arc_em_examine_target { {target ""} } { + # Will set current target + arc_v2_examine_target $target +} + +proc arc_em_init_regs { } { + arc_v2_init_regs + + [target current] configure \ + -event examine-end "arc_em_examine_target [target current]" +} + +# Scripts in "target" folder should call this function instead of direct +# invocation of arc_common_reset. +proc arc_em_reset { {target ""} } { + arc_v2_reset $target + + # Set DEBUG.ED bit to enable clock in actionpoint module. + # This is specific to ARC EM. + set debug [arc jtag get-aux-reg 5] + if { !($debug & (1 << 20)) } { + arc jtag set-aux-reg 5 [expr $debug | (1 << 20)] + } +} diff --git a/tcl/cpu/arc/v2.tcl b/tcl/cpu/arc/v2.tcl new file mode 100644 index 000000000..ad55361a5 --- /dev/null +++ b/tcl/cpu/arc/v2.tcl @@ -0,0 +1,288 @@ +# Copyright (C) 2015, 2020 Synopsys, Inc. +# Anton Kolesov +# Didin Evgeniy +# +# SPDX-License-Identifier: GPL-2.0-or-later + +source [find cpu/arc/common.tcl] + +# Currently 'examine_target' can only read JTAG registers and set properties - +# but it shouldn't write any of registers - writes will be cached, but cache +# will be invalidated before flushing after examine_target, and changes will be +# lost. Perhaps that would be fixed later - perhaps writes shouldn't be cached +# after all. But if write to register is really needed from TCL - then it +# should be done via "arc jtag" for now. +proc arc_v2_examine_target { {target ""} } { + # Set current target, because OpenOCD event handlers don't do this for us. + if { $target != "" } { + targets $target + } + + # Those registers always exist. DEBUG and DEBUGI are formally optional, + # however they come with JTAG interface, and so far there is no way + # OpenOCD can communicate with target without JTAG interface. + arc set-reg-exists identity pc status32 bta debug lp_start lp_end \ + eret erbta erstatus ecr efa + + # 32 core registers + arc set-reg-exists \ + r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 \ + r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 \ + gp fp sp ilink r30 blink lp_count pcl + + # DCCM + set dccm_version [arc get-reg-field dccm_build version] + if { $dccm_version == 3 || $dccm_version == 4 } { + arc set-reg-exists aux_dccm + } + + # ICCM + if { [arc get-reg-field iccm_build version] == 4 } { + arc set-reg-exists aux_iccm + } + + # MPU + if { [arc get-reg-field mpu_build version] >= 2 && + [arc get-reg-field mpu_build version] <= 4 } { + arc set-reg-exists mpu_en mpu_ecr + set mpu_regions [arc get-reg-field mpu_build regions] + for {set i 0} {$i < $mpu_regions} {incr i} { + arc set-reg-exists mpu_rdp$i mpu_rdb$i + } + + # Secure MPU + if { [arc get-reg-field mpu_build version] == 4 } { + arc set-reg-exists mpu_index mpu_rstart mpu_rend mpu_rper + } + } +} + +proc arc_v2_init_regs { } { + # XML features + set core_feature "org.gnu.gdb.arc.core.v2" + set aux_min_feature "org.gnu.gdb.arc.aux-minimal" + set aux_other_feature "org.gnu.gdb.arc.aux-other" + + # Describe types + # Types are sorted alphabetically according to their name. + arc add-reg-type-struct -name ap_build_t -bitfield version 0 7 \ + -bitfield type 8 11 + arc add-reg-type-struct -name ap_control_t -bitfield at 0 3 -bitfield tt 4 5 \ + -bitfield m 6 6 -bitfield p 7 7 -bitfield aa 8 8 -bitfield q 9 9 + # Cycles field added in version 4. + arc add-reg-type-struct -name dccm_build_t -bitfield version 0 7 \ + -bitfield size0 8 11 -bitfield size1 12 15 -bitfield cycles 17 19 + + arc add-reg-type-struct -name debug_t \ + -bitfield fh 1 1 -bitfield ah 2 2 -bitfield asr 3 10 \ + -bitfield is 11 11 -bitfield ep 19 19 -bitfield ed 20 20 \ + -bitfield eh 21 21 -bitfield ra 22 22 -bitfield zz 23 23 \ + -bitfield sm 24 26 -bitfield ub 28 28 -bitfield bh 29 29 \ + -bitfield sh 30 30 -bitfield ld 31 31 + + arc add-reg-type-struct -name ecr_t \ + -bitfield parameter 0 7 \ + -bitfield cause 8 15 \ + -bitfield vector 16 23 \ + -bitfield U 30 30 \ + -bitfield P 31 31 + arc add-reg-type-struct -name iccm_build_t -bitfield version 0 7 \ + -bitfield iccm0_size0 8 11 -bitfield iccm1_size0 12 15 \ + -bitfield iccm0_size1 16 19 -bitfield iccm1_size1 20 23 + arc add-reg-type-struct -name identity_t \ + -bitfield arcver 0 7 -bitfield arcnum 8 15 -bitfield chipid 16 31 + arc add-reg-type-struct -name isa_config_t -bitfield version 0 7 \ + -bitfield pc_size 8 11 -bitfield lpc_size 12 15 -bitfield addr_size 16 19 \ + -bitfield b 20 20 -bitfield a 21 21 -bitfield n 22 22 -bitfield l 23 23 \ + -bitfield c 24 27 -bitfield d 28 31 + arc add-reg-type-struct -name mpu_build_t -bitfield version 0 7 \ + -bitfield regions 8 15 \ + -bitfield s 16 16 \ + -bitfield i 17 17 + arc add-reg-type-struct -name mpu_ecr_t \ + -bitfield MR 0 7 \ + -bitfield VT 8 9 \ + -bitfield EC_CODE 16 31 + arc add-reg-type-struct -name mpu_en_t \ + -bitfield UE 3 3 -bitfield UW 4 4 -bitfield UR 5 5 \ + -bitfield KE 6 6 -bitfield KW 7 7 -bitfield KR 8 8 \ + -bitfield S 15 15 -bitfield SID 16 23 \ + -bitfield EN 30 30 + arc add-reg-type-struct -name mpu_index_t \ + -bitfield I 0 3 -bitfield M 30 30 -bitfield D 31 31 + arc add-reg-type-struct -name mpu_rper_t \ + -bitfield V 0 0 \ + -bitfield UE 3 3 -bitfield UW 4 4 -bitfield UR 5 5 \ + -bitfield KE 6 6 -bitfield KW 7 7 -bitfield KR 8 8 \ + -bitfield S 15 15 -bitfield SID 16 23 + arc add-reg-type-flags -name status32_t \ + -flag H 0 -flag E0 1 -flag E1 2 -flag E2 3 \ + -flag E3 4 -flag AE 5 -flag DE 6 -flag U 7 \ + -flag V 8 -flag C 9 -flag N 10 -flag Z 11 \ + -flag L 12 -flag DZ 13 -flag SC 14 -flag ES 15 \ + -flag RB0 16 -flag RB1 17 -flag RB2 18 \ + -flag AD 19 -flag US 20 -flag IE 31 + + # Core registers + set core_regs { + r0 0 uint32 + r1 1 uint32 + r2 2 uint32 + r3 3 uint32 + r4 4 uint32 + r5 5 uint32 + r6 6 uint32 + r7 7 uint32 + r8 8 uint32 + r9 9 uint32 + r10 10 uint32 + r11 11 uint32 + r12 12 uint32 + r13 13 uint32 + r14 14 uint32 + r15 15 uint32 + r16 16 uint32 + r17 17 uint32 + r18 18 uint32 + r19 19 uint32 + r20 20 uint32 + r21 21 uint32 + r22 23 uint32 + r23 24 uint32 + r24 24 uint32 + r25 25 uint32 + gp 26 data_ptr + fp 27 data_ptr + sp 28 data_ptr + ilink 29 code_ptr + r30 30 uint32 + blink 31 code_ptr + r32 32 uint32 + r33 33 uint32 + r34 34 uint32 + r35 35 uint32 + r36 36 uint32 + r37 37 uint32 + r38 38 uint32 + r39 39 uint32 + r40 40 uint32 + r41 41 uint32 + r42 42 uint32 + r43 43 uint32 + r44 44 uint32 + r45 45 uint32 + r46 46 uint32 + r47 47 uint32 + r48 48 uint32 + r49 49 uint32 + r50 50 uint32 + r51 51 uint32 + r52 52 uint32 + r53 53 uint32 + r54 54 uint32 + r55 55 uint32 + r56 56 uint32 + r57 57 uint32 + accl 58 uint32 + acch 59 uint32 + lp_count 60 uint32 + limm 61 uint32 + reserved 62 uint32 + pcl 63 code_ptr + } + foreach {reg count type} $core_regs { + arc add-reg -name $reg -num $count -core -type $type -g \ + -feature $core_feature + } + + # AUX min + set aux_min { + 0x6 pc code_ptr + 0x2 lp_start code_ptr + 0x3 lp_end code_ptr + 0xA status32 status32_t + } + foreach {num name type} $aux_min { + arc add-reg -name $name -num $num -type $type -feature $aux_min_feature -g + } + + # AUX other + set aux_other { + 0x004 identity identity_t + 0x005 debug debug_t + 0x018 aux_dccm int + 0x208 aux_iccm int + + + 0x400 eret code_ptr + 0x401 erbta code_ptr + 0x402 erstatus status32_t + 0x403 ecr ecr_t + 0x404 efa data_ptr + + 0x409 mpu_en mpu_en_t + + 0x412 bta code_ptr + + 0x420 mpu_ecr mpu_ecr_t + 0x422 mpu_rdb0 int + 0x423 mpu_rdp0 int + 0x424 mpu_rdb1 int + 0x425 mpu_rdp1 int + 0x426 mpu_rdb2 int + 0x427 mpu_rdp2 int + 0x428 mpu_rdb3 int + 0x429 mpu_rdp3 int + 0x42A mpu_rdb4 int + 0x42B mpu_rdp4 int + 0x42C mpu_rdb5 int + 0x42D mpu_rdp5 int + 0x42E mpu_rdb6 int + 0x42F mpu_rdp6 int + 0x430 mpu_rdb7 int + 0x431 mpu_rdp7 int + 0x432 mpu_rdb8 int + 0x433 mpu_rdp8 int + 0x434 mpu_rdb9 int + 0x435 mpu_rdp9 int + 0x436 mpu_rdb10 int + 0x437 mpu_rdp10 int + 0x438 mpu_rdb11 int + 0x439 mpu_rdp11 int + 0x43A mpu_rdb12 int + 0x43B mpu_rdp12 int + 0x43C mpu_rdb13 int + 0x43D mpu_rdp13 int + 0x43E mpu_rdb14 int + 0x43F mpu_rdp14 int + 0x440 mpu_rdb15 int + 0x441 mpu_rdp15 int + 0x448 mpu_index mpu_index_t + 0x449 mpu_rstart uint32 + 0x44A mpu_rend uint32 + 0x44B mpu_rper mpu_rper_t + 0x44C mpu_probe uint32 + } + foreach {num name type} $aux_other { + arc add-reg -name $name -num $num -type $type -feature $aux_other_feature + } + + # AUX BCR + set bcr { + 0x6D mpu_build + 0x74 dccm_build + 0x76 ap_build + 0x78 iccm_build + 0xC1 isa_config + } + foreach {num reg} $bcr { + arc add-reg -name $reg -num $num -type ${reg}_t -bcr -feature $aux_other_feature + } + + [target current] configure \ + -event examine-end "arc_v2_examine_target [target current]" +} + +proc arc_v2_reset { {target ""} } { + arc_common_reset $target +} diff --git a/tcl/target/snps_em_sk_fpga.cfg b/tcl/target/snps_em_sk_fpga.cfg new file mode 100644 index 000000000..d52c7e8db --- /dev/null +++ b/tcl/target/snps_em_sk_fpga.cfg @@ -0,0 +1,34 @@ +# Copyright (C) 2014-2015,2020 Synopsys, Inc. +# Anton Kolesov +# Didin Evgeniy +# +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Xilinx Spartan-6 XC6SLX45 FPGA on EM Starter Kit v1. +# Xilinx Spartan-6 XC6SLX150 FPGA on EM Starter Kit v2. +# + +source [find cpu/arc/em.tcl] + +set _CHIPNAME arc-em +set _TARGETNAME $_CHIPNAME.cpu + +# EM SK IDENTITY is 0x200444b1 +# EM SK v2 IDENTITY is 0x200044b1 +jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -expected-id 0x200444b1 \ + -expected-id 0x200044b1 + +set _coreid 0 +set _dbgbase [expr 0x00000000 | ($_coreid << 13)] + +target create $_TARGETNAME arcv2 -chain-position $_TARGETNAME \ + -coreid 0 -dbgbase $_dbgbase -endian little + +# There is no SRST, so do a software reset +$_TARGETNAME configure -event reset-assert "arc_em_reset $_TARGETNAME" + +arc_em_init_regs + +# vim:ft=tcl + From a7d98680e20bf8eccb9a7ccc67fef390ddb90f03 Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Thu, 28 Nov 2019 08:34:46 +0300 Subject: [PATCH 248/354] Add documentation section for ARCv2 Changes since v1: -Moved from http://openocd.zylin.com/#/c/5332/4 into separate commit. 28.02.2020: -Removed multiple cpu configuration section, currently only ARC EM is supported. 17.03.2020: -Some cleanup -For "arc set-reg-exists" command limitize the number of arguments (50 maximum). 17.03.2020(v2): -Revert limitation for "arc set-reg-exist" command Change-Id: I4b06f89df95f2773bfde6e1bd2ae2b6b880bfaa8 Signed-off-by: Evgeniy Didin Cc: Alexey Brodkin Reviewed-on: http://openocd.zylin.com/5351 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- doc/openocd.texi | 129 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/doc/openocd.texi b/doc/openocd.texi index 0c58a682c..35a41d4de 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -9685,6 +9685,135 @@ Perform a 32-bit DMI read at address, returning the value. Perform a 32-bit DMI write of value at address. @end deffn +@section ARC Architecture +@cindex ARC + +Synopsys DesignWare ARC Processors are a family of 32-bit CPUs that SoC +designers can optimize for a wide range of uses, from deeply embedded to +high-performance host applications in a variety of market segments. See more +at: http://www.synopsys.com/IP/ProcessorIP/ARCProcessors/Pages/default.aspx. +OpenOCD currently supports ARC EM processors. +There is a set ARC-specific OpenOCD commands that allow low-level +access to the core and provide necessary support for ARC extensibility and +configurability capabilities. ARC processors has much more configuration +capabilities than most of the other processors and in addition there is an +extension interface that allows SoC designers to add custom registers and +instructions. For the OpenOCD that mostly means that set of core and AUX +registers in target will vary and is not fixed for a particular processor +model. To enable extensibility several TCL commands are provided that allow to +describe those optional registers in OpenOCD configuration files. Moreover +those commands allow for a dynamic target features discovery. + + +@subsection General ARC commands + +@deffn {Config Command} {arc add-reg} configparams + +Add a new register to processor target. By default newly created register is +marked as not existing. @var{configparams} must have following required +arguments: + +@itemize @bullet + +@item @code{-name} name +@*Name of a register. + +@item @code{-num} number +@*Architectural register number: core register number or AUX register number. + +@item @code{-feature} XML_feature +@*Name of GDB XML target description feature. + +@end itemize + +@var{configparams} may have following optional arguments: + +@itemize @bullet + +@item @code{-gdbnum} number +@*GDB register number. It is recommended to not assign GDB register number +manually, because there would be a risk that two register will have same +number. When register GDB number is not set with this option, then register +will get a previous register number + 1. This option is required only for those +registers that must be at particular address expected by GDB. + +@item @code{-core} +@*This option specifies that register is a core registers. If not - this is an +AUX register. AUX registers and core registers reside in different address +spaces. + +@item @code{-bcr} +@*This options specifies that register is a BCR register. BCR means Build +Configuration Registers - this is a special type of AUX registers that are read +only and non-volatile, that is - they never change their value. Therefore OpenOCD +never invalidates values of those registers in internal caches. Because BCR is a +type of AUX registers, this option cannot be used with @code{-core}. + +@item @code{-type} type_name +@*Name of type of this register. This can be either one of the basic GDB types, +or a custom types described with @command{arc add-reg-type-[flags|struct]}. + +@item @code{-g} +@* If specified then this is a "general" register. General registers are always +read by OpenOCD on context save (when core has just been halted) and is always +transfered to GDB client in a response to g-packet. Contrary to this, +non-general registers are read and sent to GDB client on-demand. In general it +is not recommended to apply this option to custom registers. + +@end itemize + +@end deffn + +@deffn {Config Command} {arc add-reg-type-flags} -name name flags... +Adds new register type of ``flags'' class. ``Flags'' types can contain only +one-bit fields. Each flag definition looks like @code{-flag name bit-position}. +@end deffn + +@anchor{add-reg-type-struct} +@deffn {Config Command} {arc add-reg-type-struct} -name name structs... +Adds new register type of ``struct'' class. ``Struct'' types can contain either +bit-fields or fields of other types, however at the moment only bit fields are +supported. Structure bit field definition looks like @code{-bitfield name +startbit endbit}. +@end deffn + +@deffn {Command} {arc get-reg-field} reg-name field-name +Returns value of bit-field in a register. Register must be ``struct'' register +type, @xref{add-reg-type-struct} command definition. +@end deffn + +@deffn {Command} {arc set-reg-exists} reg-names... +Specify that some register exists. Any amount of names can be passed +as an argument for a single command invocation. +@end deffn + +@subsection ARC JTAG commands + +@deffn {Command} {arc jtag set-aux-reg} regnum value +This command writes value to AUX register via its number. This command access +register in target directly via JTAG, bypassing any OpenOCD internal caches, +therefore it is unsafe to use if that register can be operated by other means. + +@end deffn + +@deffn {Command} {arc jtag set-core-reg} regnum value +This command is similiar to @command{arc jtag set-aux-reg} but is for core +registers. +@end deffn + +@deffn {Command} {arc jtag get-aux-reg} regnum +This command returns the value storded in AUX register via its number. This commands access +register in target directly via JTAG, bypassing any OpenOCD internal caches, +therefore it is unsafe to use if that register can be operated by other means. + +@end deffn + +@deffn {Command} {arc jtag get-core-reg} regnum +This command is similiar to @command{arc jtag get-aux-reg} but is for core +registers. +@end deffn + + @anchor{softwaredebugmessagesandtracing} @section Software Debug Messages and Tracing @cindex Linux-ARM DCC support From ea4f98046fe2f9d8362feadb50f058a9fff7ad4f Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Tue, 17 Mar 2020 14:06:24 +0300 Subject: [PATCH 249/354] target/arc: remove saving context during reset In arc_poll() function we handle the cases, when jtag indicates, that processor is halted, but target->state is not TARGET_HALTED. In case, when processor was halted and target->state was TARGET_RUNNING, we should save context. At the same time if target->state was TARGET_RESET we do not need to save context. Changes: 16.04: Fix - Move setting target->state = TARGET_HALT after "target->state == TARGET_RUNNIG" check, otherwise this check makes no sense Change-Id: I92ab6ec71cf58273bb8401d14a562035de3deab4 Signed-off-by: Evgeniy Didin Reviewed-on: http://openocd.zylin.com/5524 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/arc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/target/arc.c b/src/target/arc.c index 244dd5247..823b9ed70 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -928,8 +928,10 @@ static int arc_poll(struct target *target) CHECK_RETVAL(arc_get_register_value(target, "status32", &value)); if (value & AUX_STATUS32_REG_HALT_BIT) { LOG_DEBUG("ARC core in halt or reset state."); + /* Save context if target was not in reset state */ + if (target->state == TARGET_RUNNING) + CHECK_RETVAL(arc_debug_entry(target)); target->state = TARGET_HALTED; - CHECK_RETVAL(arc_debug_entry(target)); CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); } else { LOG_DEBUG("Discrepancy of STATUS32[0] HALT bit and ARC_JTAG_STAT_RU, " From 46f077aa003449f95781170fc2d0cf674272ad3e Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 13 Mar 2020 12:10:50 +0100 Subject: [PATCH 250/354] flash/nand/core: fix clang static analyzer warning core.c:446: The left operand of '>>' is a garbage value There are many places where an error code returned from nand->controller operations are ignored. To keep the change minimal, the error checks are added only to reading of extended nand info as it was suspected to be the cause of the warning. Addition of the error checks did not fix the warning. scan-build-9 report was inspected and IMHO the warning is bogus: the term (nand->device->erase_size == 0) cannot give false at line 395 and then evaluate true at line 462. Fixed by zeroing id_buff. Change-Id: I97ed7ce0fdf1aa23d746d5fb898bacd050e20ae8 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5518 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Oleksij Rempel --- src/flash/nand/core.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/flash/nand/core.c b/src/flash/nand/core.c index b9ac793f2..baef5d59c 100644 --- a/src/flash/nand/core.c +++ b/src/flash/nand/core.c @@ -263,6 +263,7 @@ int nand_read_status(struct nand_device *nand, uint8_t *status) return ERROR_NAND_DEVICE_NOT_PROBED; /* Send read status command */ + /* FIXME: errors returned from nand->controller are mostly ignored! */ nand->controller->command(nand, NAND_CMD_STATUS); alive_sleep(1); @@ -301,7 +302,8 @@ static int nand_poll_ready(struct nand_device *nand, int timeout) int nand_probe(struct nand_device *nand) { uint8_t manufacturer_id, device_id; - uint8_t id_buff[6]; + uint8_t id_buff[6] = { 0 }; /* zero buff to silence false warning + * from clang static analyzer */ int retval; int i; @@ -392,19 +394,34 @@ int nand_probe(struct nand_device *nand) if (nand->device->page_size == 0 || nand->device->erase_size == 0) { if (nand->bus_width == 8) { - nand->controller->read_data(nand, id_buff + 3); - nand->controller->read_data(nand, id_buff + 4); - nand->controller->read_data(nand, id_buff + 5); + retval = nand->controller->read_data(nand, id_buff + 3); + if (retval != ERROR_OK) + return retval; + + retval = nand->controller->read_data(nand, id_buff + 4); + if (retval != ERROR_OK) + return retval; + + retval = nand->controller->read_data(nand, id_buff + 5); + if (retval != ERROR_OK) + return retval; + } else { uint16_t data_buf; - nand->controller->read_data(nand, &data_buf); + retval = nand->controller->read_data(nand, &data_buf); + if (retval != ERROR_OK) + return retval; id_buff[3] = data_buf; - nand->controller->read_data(nand, &data_buf); + retval = nand->controller->read_data(nand, &data_buf); + if (retval != ERROR_OK) + return retval; id_buff[4] = data_buf; - nand->controller->read_data(nand, &data_buf); + retval = nand->controller->read_data(nand, &data_buf); + if (retval != ERROR_OK) + return retval; id_buff[5] = data_buf >> 8; } } From c0644401622d1d5bf42e522452c7c9f83293cfd8 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 20 Dec 2019 23:34:19 +0100 Subject: [PATCH 251/354] jtag/drivers/ulink: fix clang static analyzer warning scan-build-9: Description: Potential leak of memory pointed to by 'tdo_buffer' File: src/jtag/drivers/ulink.c Line: 1629 Free the buffer before error return. Change-Id: Ic47651a5ae78c7a47ae4fcbad225f329b14c45cb Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5519 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Oleksij Rempel --- src/jtag/drivers/ulink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index 77fbe6193..9235eb893 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -1627,6 +1627,7 @@ int ulink_queue_scan(struct ulink *device, struct jtag_command *cmd) if (ret != ERROR_OK) { free(tdi_buffer_start); + free(tdo_buffer_start); return ret; } } From 6dcd255b7bde5d7d3a8805c3a0e81f5edf42ccf4 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 13 Mar 2020 15:13:21 +0100 Subject: [PATCH 252/354] jtag/drivers/ulink: fix clang static analyzer warning scan-build-9: Description: Access to field 'payload_in' results in a dereference of a null pointer (loaded from field 'queue_start') File: src/jtag/drivers/ulink.c Line: 2216 Set input/output_signals conditionally if ulink_append_get_signals_cmd() and ulink_execute_queued_commands() returns no error. Do not fail driver initialisation as the signals are only printed. Change-Id: I6c842f0e9a604712abf7444a2fa95ba5810de1ff Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5520 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Oleksij Rempel --- src/jtag/drivers/ulink.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index 9235eb893..4066d6109 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -2210,14 +2210,17 @@ static int ulink_init(void) } ulink_clear_queue(ulink_handle); - ulink_append_get_signals_cmd(ulink_handle); - ulink_execute_queued_commands(ulink_handle, 200); + ret = ulink_append_get_signals_cmd(ulink_handle); + if (ret == ERROR_OK) + ret = ulink_execute_queued_commands(ulink_handle, 200); - /* Post-process the single CMD_GET_SIGNALS command */ - input_signals = ulink_handle->queue_start->payload_in[0]; - output_signals = ulink_handle->queue_start->payload_in[1]; + if (ret == ERROR_OK) { + /* Post-process the single CMD_GET_SIGNALS command */ + input_signals = ulink_handle->queue_start->payload_in[0]; + output_signals = ulink_handle->queue_start->payload_in[1]; - ulink_print_signal_states(input_signals, output_signals); + ulink_print_signal_states(input_signals, output_signals); + } ulink_clear_queue(ulink_handle); From 3c296bd19480033037f4e3f2db4a876a34a41f58 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 13 Mar 2020 15:34:47 +0100 Subject: [PATCH 253/354] jtag/drivers/ulink: fix clang static analyzer warnings scan-build-9: Description: Potential leak of memory pointed to by 'cmd' File: /home/vanekt/openocd/scanbuild9/../src/jtag/drivers/ulink.c Line: 1075 Description: Potential leak of memory pointed to by 'cmd' File: /home/vanekt/openocd/scanbuild9/../src/jtag/drivers/ulink.c Line: 1275 ulink_append_xxx_cmd() functions allocate memory for cmd and then call ulink_allocate_payload(), which allocates cmd->payload_out or cmd->payload_in. ulink_append_queue() checks the size of queue and if the new payload does not fit, calls ulink_execute_queued_commands() and then ulink_post_process_queue(). If any of these two fails, an error is returned, allocated cmd struct leaks and the queue is left in an undefined state. Change ulink_append_queue() flow to proceed to appending cmd to the queue even in the case of fail in previous ulink_execute_queued_commands() or ulink_post_process_queue(). In case of fail then clear the queue including the last appended cmd. Change-Id: I967c07af19e9020c93bcb4ef403cf1f557dd1db1 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5370 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/jtag/drivers/ulink.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index 4066d6109..c6683abda 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -650,7 +650,7 @@ void ulink_clear_queue(struct ulink *device) int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd) { int newsize_out, newsize_in; - int ret; + int ret = ERROR_OK; newsize_out = ulink_get_queue_size(device, PAYLOAD_DIRECTION_OUT) + 1 + ulink_cmd->payload_out_size; @@ -663,14 +663,12 @@ int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd) /* New command does not fit. Execute all commands in queue before starting * new queue with the current command as first entry. */ ret = ulink_execute_queued_commands(device, USB_TIMEOUT); - if (ret != ERROR_OK) - return ret; - ret = ulink_post_process_queue(device); - if (ret != ERROR_OK) - return ret; + if (ret == ERROR_OK) + ret = ulink_post_process_queue(device); - ulink_clear_queue(device); + if (ret == ERROR_OK) + ulink_clear_queue(device); } if (device->queue_start == NULL) { @@ -687,7 +685,10 @@ int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd) device->queue_end = ulink_cmd; } - return ERROR_OK; + if (ret != ERROR_OK) + ulink_clear_queue(device); + + return ret; } /** From 7a94d0a19fbe1762d1be26d35958ca3edb74b41e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 14 Feb 2020 16:49:45 +0100 Subject: [PATCH 254/354] tcl: stm32mp15x: add target and board config files The stm32mp15x has one or two Cortex-A7 (depending on the P/N) and one Cortex-M4. The second core is automatically detected by the target script. In "engineering boot" all the cores are accessible. In "production boot" the Cortex-M4 is kept in reset state after power-on or NRST. The board DK2 includes a ST-Link/V2, but only SWD is connected. Change-Id: Ib6ebefcc696b1716e0f98694cadf0b04fd7d11d6 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5454 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/board/stm32mp15x_dk2.cfg | 11 ++++ tcl/target/stm32mp15x.cfg | 121 +++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 tcl/board/stm32mp15x_dk2.cfg create mode 100644 tcl/target/stm32mp15x.cfg diff --git a/tcl/board/stm32mp15x_dk2.cfg b/tcl/board/stm32mp15x_dk2.cfg new file mode 100644 index 000000000..0233c6d75 --- /dev/null +++ b/tcl/board/stm32mp15x_dk2.cfg @@ -0,0 +1,11 @@ +# board MB1272B +# http://www.st.com/en/evaluation-tools/stm32mp157a-dk1.html +# http://www.st.com/en/evaluation-tools/stm32mp157c-dk2.html + +source [find interface/stlink-dap.cfg] + +transport select dapdirect_swd + +source [find target/stm32mp15x.cfg] + +reset_config srst_only diff --git a/tcl/target/stm32mp15x.cfg b/tcl/target/stm32mp15x.cfg new file mode 100644 index 000000000..a11f6665e --- /dev/null +++ b/tcl/target/stm32mp15x.cfg @@ -0,0 +1,121 @@ +# STMicroelectronics STM32MP15x (Single/Dual Cortex-A7 plus Cortex-M4) +# http://www.st.com/stm32mp1 + +# HLA does not support multi-cores nor custom CSW nor AP other than 0 +if { [using_hla] } { + echo "ERROR: HLA transport cannot work with this target." + echo "ERROR: To use STLink switch to DAP mode, as in \"board/stm32mp15x_dk2.cfg\"." + shutdown +} + +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME stm32mp15x +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + if { [using_jtag] } { + set _CPUTAPID 0x6ba00477 + } else { + set _CPUTAPID 0x6ba02477 + } +} + +# Chip Level TAP Controller, only in jtag mode +if { [info exists CLCTAPID] } { + set _CLCTAPID $CLCTAPID +} else { + set _CLCTAPID 0x06500041 +} + +swj_newdap $_CHIPNAME tap -expected-id $_CPUTAPID -irlen 4 +if { [using_jtag] } { + jtag newtap $_CHIPNAME.clc tap -expected-id $_CLCTAPID -irlen 5 +} + +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap -ignore-syspwrupack + +# FIXME: Cortex-M code requires target accessible during reset, but this is not possible in STM32MP1 +# so defer-examine it until the reset framework get merged +# NOTE: keep ap-num and dbgbase to speed-up examine after reset +# NOTE: do not change the order of target create +target create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1 +target create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2 +target create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0 +target create $_CHIPNAME.cpu0 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000 +target create $_CHIPNAME.cpu1 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 1 -dbgbase 0xE00D2000 +target create $_CHIPNAME.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -defer-examine + +targets $_CHIPNAME.cpu0 + +target smp $_CHIPNAME.cpu0 $_CHIPNAME.cpu1 +$_CHIPNAME.cpu0 cortex_a maskisr on +$_CHIPNAME.cpu1 cortex_a maskisr on +$_CHIPNAME.cpu0 cortex_a dacrfixup on +$_CHIPNAME.cpu1 cortex_a dacrfixup on + +cti create $_CHIPNAME.cti.sys -dap $_CHIPNAME.dap -ap-num 1 -ctibase 0xE0094000 +cti create $_CHIPNAME.cti.cpu0 -dap $_CHIPNAME.dap -ap-num 1 -ctibase 0xE00D8000 +cti create $_CHIPNAME.cti.cpu1 -dap $_CHIPNAME.dap -ap-num 1 -ctibase 0xE00D9000 +cti create $_CHIPNAME.cti.cm4 -dap $_CHIPNAME.dap -ap-num 2 -ctibase 0xE0043000 + +# interface does not work while srst is asserted +# this is target specific, valid for every board +# Errata "2.3.5 Incorrect reset of glitch-free kernel clock switch" requires +# srst to force VDDCORE power cycle or pull srst_core. Both cases reset the +# debug unit, behavior equivalent to "srst_pulls_trst" +reset_config srst_gates_jtag srst_pulls_trst + +adapter speed 5000 +adapter srst pulse_width 200 +# bootrom has an internal timeout of 1 second for detecting the boot flash. +# wait at least 1 second to guarantee we are out of bootrom +adapter srst delay 1100 + +add_help_text axi_secure "Set secure mode for following AXI accesses" +proc axi_secure {} { + $::_CHIPNAME.dap apsel 0 + $::_CHIPNAME.dap apcsw 0x10006000 +} + +add_help_text axi_nsecure "Set non-secure mode for following AXI accesses" +proc axi_nsecure {} { + $::_CHIPNAME.dap apsel 0 + $::_CHIPNAME.dap apcsw 0x30006000 +} + +axi_secure + +proc dbgmcu_enable_debug {} { + # set debug enable bits in DBGMCU_CR to get ap2 and cm4 visible + catch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000007} +} + +proc toggle_cpu0_dbg_claim0 {} { + # toggle CPU0 DBG_CLAIM[0] + $::_CHIPNAME.ap1 mww 0xe00d0fa0 1 + $::_CHIPNAME.ap1 mww 0xe00d0fa4 1 +} + +proc detect_cpu1 {} { + $::_CHIPNAME.ap1 mem2array cpu1_prsr 32 0xE00D2314 1 + set dual_core [expr $cpu1_prsr(0) & 1] + if {! $dual_core} {$::_CHIPNAME.cpu1 configure -defer-examine} +} + +# FIXME: most of handler below will be removed once reset framework get merged +$_CHIPNAME.ap1 configure -event reset-deassert-pre {adapter deassert srst deassert trst;dap init;catch {$::_CHIPNAME.dap apid 1}} +$_CHIPNAME.ap2 configure -event reset-deassert-pre {dbgmcu_enable_debug} +$_CHIPNAME.cpu0 configure -event reset-deassert-pre {$::_CHIPNAME.cpu0 arp_examine} +$_CHIPNAME.cpu1 configure -event reset-deassert-pre {$::_CHIPNAME.cpu1 arp_examine allow-defer} +$_CHIPNAME.cpu0 configure -event reset-deassert-post {toggle_cpu0_dbg_claim0} +$_CHIPNAME.cm4 configure -event reset-deassert-post {$::_CHIPNAME.cm4 arp_examine;if {[$::_CHIPNAME.ap2 curstate] == "halted"} {$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_halt}} +$_CHIPNAME.ap1 configure -event examine-start {dap init} +$_CHIPNAME.ap2 configure -event examine-start {dbgmcu_enable_debug} +$_CHIPNAME.cpu0 configure -event examine-end {detect_cpu1} +$_CHIPNAME.ap2 configure -event examine-end {$::_CHIPNAME.cm4 arp_examine} From 278c7adcce51ca11c30b7dd5c178fa28d19dc4e6 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 4 Apr 2020 13:20:56 +0200 Subject: [PATCH 255/354] tcl/target: Drop reference to renesas_gen2_common.cfg Drop bogus reference to board/renesas_gen2_common.cfg , which is a non-existing file. Fixes: a01474bb4c4c ("tcl/target: Switch Renesas R-Car Gen2 boards to new config") Change-Id: Icb22d8456b7ac94d3a9a4ed354b246ee1332b122 Signed-off-by: Marek Vasut Reviewed-on: http://openocd.zylin.com/5564 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- tcl/board/renesas_porter.cfg | 1 - tcl/board/renesas_silk.cfg | 1 - tcl/board/renesas_stout.cfg | 1 - 3 files changed, 3 deletions(-) diff --git a/tcl/board/renesas_porter.cfg b/tcl/board/renesas_porter.cfg index b5622e683..7f23fb63c 100644 --- a/tcl/board/renesas_porter.cfg +++ b/tcl/board/renesas_porter.cfg @@ -2,4 +2,3 @@ set SOC M2 source [find target/renesas_rcar_gen2.cfg] -source [find board/renesas_gen2_common.cfg] diff --git a/tcl/board/renesas_silk.cfg b/tcl/board/renesas_silk.cfg index 36af47ff4..08bcb666f 100644 --- a/tcl/board/renesas_silk.cfg +++ b/tcl/board/renesas_silk.cfg @@ -2,4 +2,3 @@ set SOC E2 source [find target/renesas_rcar_gen2.cfg] -source [find board/renesas_gen2_common.cfg] diff --git a/tcl/board/renesas_stout.cfg b/tcl/board/renesas_stout.cfg index 7a8001796..51b53e154 100644 --- a/tcl/board/renesas_stout.cfg +++ b/tcl/board/renesas_stout.cfg @@ -2,4 +2,3 @@ set SOC H2 source [find target/renesas_rcar_gen2.cfg] -source [find board/renesas_gen2_common.cfg] From 76a1524b5e4b89149d7126b681c935de4aaa441a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 10 Apr 2019 12:46:54 +0200 Subject: [PATCH 256/354] tools/checkpatch.sh: remove flag --no-tree Commit c5d89883165e02ea4f318e3cb0ba40d1fb6f04d1 ("checkpatch.pl: check for openocd tree, not for kernel tree") has already fixed the check for OpenOCD tree, thus we do not need to skip it in the shell wrapper. Remove flag --no-tree from the shell wrapper. Change-Id: I8be497258624d89bde7742fee141a8f56bf9188e Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5110 Tested-by: jenkins --- tools/checkpatch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/checkpatch.sh b/tools/checkpatch.sh index e1dd267f9..0a630a248 100755 --- a/tools/checkpatch.sh +++ b/tools/checkpatch.sh @@ -2,4 +2,4 @@ # since=${1:-HEAD^} -git format-patch -M --stdout $since | tools/scripts/checkpatch.pl - --no-tree +git format-patch -M --stdout $since | tools/scripts/checkpatch.pl - From 699a8475a1cdc4a374470f1269106534102db148 Mon Sep 17 00:00:00 2001 From: Liming Sun Date: Fri, 10 May 2019 11:02:31 -0400 Subject: [PATCH 257/354] jtag/drivers: add debugging support for Mellanox BlueField SoC This commits adds debugging support for the Mellanox BlueField SoC via rshim, which is an interface accessible from external USB or PCIe (for SmartNIC case) via the rshim driver. It implements the arm dap interfaces based on the existing dapdirect framework. Change-Id: I18eb1c54293ec2c581f853e0e55b3f96d7978b56 Signed-off-by: Liming Sun Reviewed-on: http://openocd.zylin.com/5457 Tested-by: jenkins Reviewed-by: Antonio Borneo --- configure.ac | 20 ++ src/jtag/drivers/Makefile.am | 3 + src/jtag/drivers/rshim.c | 523 +++++++++++++++++++++++++++++++++++ src/jtag/interfaces.c | 6 + tcl/board/bluefield.cfg | 6 + tcl/interface/rshim.cfg | 6 + tcl/target/bluefield.cfg | 78 ++++++ 7 files changed, 642 insertions(+) create mode 100644 src/jtag/drivers/rshim.c create mode 100644 tcl/board/bluefield.cfg create mode 100644 tcl/interface/rshim.cfg create mode 100644 tcl/target/bluefield.cfg diff --git a/configure.ac b/configure.ac index 497b15fd1..9c2f1d7ea 100644 --- a/configure.ac +++ b/configure.ac @@ -222,6 +222,12 @@ AC_ARG_ENABLE([dummy], AS_HELP_STRING([--enable-dummy], [Enable building the dummy port driver]), [build_dummy=$enableval], [build_dummy=no]) +AS_CASE([$host_os], [linux*], [host_os_linux=yes], [host_os_linux=no]) + +AC_ARG_ENABLE([rshim], + AS_HELP_STRING([--enable-rshim], [Enable building the rshim driver]), + [build_rshim=$enableval], [build_rshim=$host_os_linux]) + m4_define([AC_ARG_ADAPTERS], [ m4_foreach([adapter], [$1], [AC_ARG_ENABLE(ADAPTER_OPT([adapter]), @@ -334,6 +340,13 @@ AS_CASE([$host_os], AS_IF([test "x$build_xlnx_pcie_xvc" = "xyes"], [ AC_MSG_ERROR([xlnx_pcie_xvc is only available on linux]) ]) + + AS_CASE([$host_os], [freebsd*], [], + [ + AS_IF([test "x$build_rshim" = "xyes"], [ + AC_MSG_ERROR([build_rshim is only available on linux or freebsd]) + ]) + ]) ]) AC_ARG_ENABLE([minidriver_dummy], @@ -482,6 +495,12 @@ AS_IF([test "x$build_parport" = "xyes"], [ AC_DEFINE([BUILD_PARPORT], [0], [0 if you don't want parport.]) ]) +AS_IF([test "x$build_rshim" = "xyes"], [ + AC_DEFINE([BUILD_RSHIM], [1], [1 if you want to debug BlueField SoC via rshim.]) +], [ + AC_DEFINE([BUILD_RSHIM], [0], [0 if you don't want to debug BlueField SoC via rshim.]) +]) + AS_IF([test "x$build_dummy" = "xyes"], [ build_bitbang=yes AC_DEFINE([BUILD_DUMMY], [1], [1 if you want dummy driver.]) @@ -730,6 +749,7 @@ AM_CONDITIONAL([USE_LIBFTDI], [test "x$use_libftdi" = "xyes"]) AM_CONDITIONAL([USE_HIDAPI], [test "x$use_hidapi" = "xyes"]) AM_CONDITIONAL([USE_LIBJAYLINK], [test "x$use_libjaylink" = "xyes"]) AM_CONDITIONAL([TARGET64], [test "x$build_target64" = "xyes"]) +AM_CONDITIONAL([RSHIM], [test "x$build_rshim" = "xyes"]) AM_CONDITIONAL([MINIDRIVER], [test "x$build_minidriver" = "xyes"]) AM_CONDITIONAL([MINIDRIVER_DUMMY], [test "x$build_minidriver_dummy" = "xyes"]) diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index aea09b38c..ba758e720 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -133,6 +133,9 @@ if HLADAPTER DRIVERFILES += %D%/stlink_usb.c DRIVERFILES += %D%/ti_icdi_usb.c endif +if RSHIM +DRIVERFILES += %D%/rshim.c +endif if OSBDM DRIVERFILES += %D%/osbdm.c endif diff --git a/src/jtag/drivers/rshim.c b/src/jtag/drivers/rshim.c new file mode 100644 index 000000000..c718af5d2 --- /dev/null +++ b/src/jtag/drivers/rshim.c @@ -0,0 +1,523 @@ +/* + * Copyright (c) 2020, Mellanox Technologies Ltd. - All Rights Reserved + * Liming Sun + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#include +#include + +/* Rshim channel where the CoreSight register resides. */ +#define RSH_MMIO_CHANNEL_RSHIM 0x1 + +/* APB and tile address translation. */ +#define RSH_CS_ROM_BASE 0x80000000 +#define RSH_CS_TILE_BASE 0x44000000 +#define RSH_CS_TILE_SIZE 0x04000000 + +/* + * APB-AP Identification Register + * The default value is defined in "CoreSight on-chip trace and debug + * (Revision: r1p0)", Section 3.16.5 APB-AP register summary. + */ +#define APB_AP_IDR 0x44770002 + +/* CoreSight register definition. */ +#define RSH_CORESIGHT_CTL 0x0e00 +#define RSH_CORESIGHT_CTL_GO_SHIFT 0 +#define RSH_CORESIGHT_CTL_GO_MASK 0x1ULL +#define RSH_CORESIGHT_CTL_ACTION_SHIFT 1 +#define RSH_CORESIGHT_CTL_ACTION_MASK 0x2ULL +#define RSH_CORESIGHT_CTL_ADDR_SHIFT 2 +#define RSH_CORESIGHT_CTL_ADDR_MASK 0x7ffffffcULL +#define RSH_CORESIGHT_CTL_ERR_SHIFT 31 +#define RSH_CORESIGHT_CTL_ERR_MASK 0x80000000ULL +#define RSH_CORESIGHT_CTL_DATA_SHIFT 32 +#define RSH_CORESIGHT_CTL_DATA_MASK 0xffffffff00000000ULL + +/* Util macros to access the CoreSight register. */ +#define RSH_CS_GET_FIELD(reg, field) \ + (((uint64_t)(reg) & RSH_CORESIGHT_CTL_##field##_MASK) >> \ + RSH_CORESIGHT_CTL_##field##_SHIFT) + +#define RSH_CS_SET_FIELD(reg, field, value) \ + (reg) = (((reg) & ~RSH_CORESIGHT_CTL_##field##_MASK) | \ + (((uint64_t)(value) << RSH_CORESIGHT_CTL_##field##_SHIFT) & \ + RSH_CORESIGHT_CTL_##field##_MASK)) + +#ifdef HAVE_SYS_IOCTL_H +/* Message used to program rshim via ioctl(). */ +typedef struct { + uint32_t addr; + uint64_t data; +} __attribute__((packed)) rshim_ioctl_msg; + +enum { + RSH_IOC_READ = _IOWR('R', 0, rshim_ioctl_msg), + RSH_IOC_WRITE = _IOWR('R', 1, rshim_ioctl_msg), +}; +#endif + +/* Use local variable stub for DP/AP registers. */ +static uint32_t dp_ctrl_stat; +static uint32_t dp_id_code; +static uint32_t ap_sel, ap_bank; +static uint32_t ap_csw; +static uint32_t ap_drw; +static uint32_t ap_tar, ap_tar_inc; + +/* Static functions to read/write via rshim/coresight. */ +static int (*rshim_read)(int chan, int addr, uint64_t *value); +static int (*rshim_write)(int chan, int addr, uint64_t value); +static int coresight_write(uint32_t tile, uint32_t addr, uint32_t wdata); +static int coresight_read(uint32_t tile, uint32_t addr, uint32_t *value); + +/* RShim file handler. */ +static int rshim_fd = -1; + +/* DAP error code. */ +static int rshim_dap_retval = ERROR_OK; + +/* Default rshim device. */ +#define RSHIM_DEV_PATH_DEFAULT "/dev/rshim0/rshim" +static char *rshim_dev_path; + +static int rshim_dev_read(int chan, int addr, uint64_t *value) +{ + int rc; + + addr = (addr & 0xFFFF) | (1 << 16); + rc = pread(rshim_fd, value, sizeof(*value), addr); + +#ifdef HAVE_SYS_IOCTL_H + if (rc < 0 && errno == ENOSYS) { + rshim_ioctl_msg msg; + + msg.addr = addr; + msg.data = 0; + rc = ioctl(rshim_fd, RSH_IOC_READ, &msg); + if (!rc) + *value = msg.data; + } +#endif + + return rc; +} + +static int rshim_dev_write(int chan, int addr, uint64_t value) +{ + int rc; + + addr = (addr & 0xFFFF) | (1 << 16); + rc = pwrite(rshim_fd, &value, sizeof(value), addr); + +#ifdef HAVE_SYS_IOCTL_H + if (rc < 0 && errno == ENOSYS) { + rshim_ioctl_msg msg; + + msg.addr = addr; + msg.data = value; + rc = ioctl(rshim_fd, RSH_IOC_WRITE, &msg); + } +#endif + + return rc; +} + +/* Convert AP address to tile local address. */ +static void ap_addr_2_tile(int *tile, uint32_t *addr) +{ + *addr -= RSH_CS_ROM_BASE; + + if (*addr < RSH_CS_TILE_BASE) { + *tile = 0; + } else { + *addr -= RSH_CS_TILE_BASE; + *tile = *addr / RSH_CS_TILE_SIZE + 1; + *addr = *addr % RSH_CS_TILE_SIZE; + } +} + +/* + * Write 4 bytes on the APB bus. + * tile = 0: access the root CS_ROM table + * > 0: access the ROM table of cluster (tile - 1) + */ +static int coresight_write(uint32_t tile, uint32_t addr, uint32_t wdata) +{ + uint64_t ctl = 0; + int rc; + + if (!rshim_read || !rshim_write) + return ERROR_FAIL; + + /* + * ADDR[28] - must be set to 1 due to coresight ip. + * ADDR[27:24] - linear tile id + */ + addr = (addr >> 2) | (tile << 24); + if (tile) + addr |= (1 << 28); + RSH_CS_SET_FIELD(ctl, ADDR, addr); + RSH_CS_SET_FIELD(ctl, ACTION, 0); /* write */ + RSH_CS_SET_FIELD(ctl, DATA, wdata); + RSH_CS_SET_FIELD(ctl, GO, 1); /* start */ + + rshim_write(RSH_MMIO_CHANNEL_RSHIM, RSH_CORESIGHT_CTL, ctl); + + do { + rc = rshim_read(RSH_MMIO_CHANNEL_RSHIM, + RSH_CORESIGHT_CTL, &ctl); + if (rc < 0) { + LOG_ERROR("Failed to read rshim.\n"); + return rc; + } + } while (RSH_CS_GET_FIELD(ctl, GO)); + + return ERROR_OK; +} + +static int coresight_read(uint32_t tile, uint32_t addr, uint32_t *value) +{ + uint64_t ctl = 0; + int rc; + + if (!rshim_read || !rshim_write) + return ERROR_FAIL; + + /* + * ADDR[28] - must be set to 1 due to coresight ip. + * ADDR[27:24] - linear tile id + */ + addr = (addr >> 2) | (tile << 24); + if (tile) + addr |= (1 << 28); + RSH_CS_SET_FIELD(ctl, ADDR, addr); + RSH_CS_SET_FIELD(ctl, ACTION, 1); /* read */ + RSH_CS_SET_FIELD(ctl, GO, 1); /* start */ + + rshim_write(RSH_MMIO_CHANNEL_RSHIM, RSH_CORESIGHT_CTL, ctl); + + do { + rc = rshim_read(RSH_MMIO_CHANNEL_RSHIM, + RSH_CORESIGHT_CTL, &ctl); + if (rc < 0) { + LOG_ERROR("Failed to write rshim.\n"); + return rc; + } + } while (RSH_CS_GET_FIELD(ctl, GO)); + + *value = RSH_CS_GET_FIELD(ctl, DATA); + return ERROR_OK; +} + +static int rshim_dp_q_read(struct adiv5_dap *dap, unsigned int reg, + uint32_t *data) +{ + if (!data) + return ERROR_OK; + + switch (reg) { + case DP_DPIDR: + *data = dp_id_code; + break; + + case DP_CTRL_STAT: + *data = CDBGPWRUPACK | CSYSPWRUPACK; + break; + + default: + break; + } + + return ERROR_OK; +} + +static int rshim_dp_q_write(struct adiv5_dap *dap, unsigned int reg, + uint32_t data) +{ + switch (reg) { + case DP_CTRL_STAT: + dp_ctrl_stat = data; + break; + case DP_SELECT: + ap_sel = (data & DP_SELECT_APSEL) >> 24; + ap_bank = (data & DP_SELECT_APBANK) >> 4; + break; + default: + LOG_INFO("Unknown command"); + break; + } + + return ERROR_OK; +} + +static int rshim_ap_q_read(struct adiv5_ap *ap, unsigned int reg, + uint32_t *data) +{ + uint32_t addr; + int rc = ERROR_OK, tile; + + switch (reg) { + case MEM_AP_REG_CSW: + *data = ap_csw; + break; + + case MEM_AP_REG_CFG: + *data = 0; + break; + + case MEM_AP_REG_BASE: + *data = RSH_CS_ROM_BASE; + break; + + case AP_REG_IDR: + if (ap->ap_num == 0) + *data = APB_AP_IDR; + else + *data = 0; + break; + + case MEM_AP_REG_BD0: + case MEM_AP_REG_BD1: + case MEM_AP_REG_BD2: + case MEM_AP_REG_BD3: + addr = (ap_tar & ~0xf) + (reg & 0x0C); + ap_addr_2_tile(&tile, &addr); + rc = coresight_read(tile, addr, data); + break; + + case MEM_AP_REG_DRW: + addr = (ap_tar & ~0x3) + ap_tar_inc; + ap_addr_2_tile(&tile, &addr); + rc = coresight_read(tile, addr, data); + if (!rc && (ap_csw & CSW_ADDRINC_MASK)) + ap_tar_inc += (ap_csw & 0x03) * 2; + break; + + default: + LOG_INFO("Unknown command"); + rc = ERROR_FAIL; + break; + } + + /* Track the last error code. */ + if (rc != ERROR_OK) + rshim_dap_retval = rc; + + return rc; +} + +static int rshim_ap_q_write(struct adiv5_ap *ap, unsigned int reg, + uint32_t data) +{ + int rc = ERROR_OK, tile; + uint32_t addr; + + if (ap_bank != 0) { + rshim_dap_retval = ERROR_FAIL; + return ERROR_FAIL; + } + + switch (reg) { + case MEM_AP_REG_CSW: + ap_csw = data; + break; + + case MEM_AP_REG_TAR: + ap_tar = data; + ap_tar_inc = 0; + break; + + case MEM_AP_REG_BD0: + case MEM_AP_REG_BD1: + case MEM_AP_REG_BD2: + case MEM_AP_REG_BD3: + addr = (ap_tar & ~0xf) + (reg & 0x0C); + ap_addr_2_tile(&tile, &addr); + rc = coresight_write(tile, addr, data); + break; + + case MEM_AP_REG_DRW: + ap_drw = data; + addr = (ap_tar & ~0x3) + ap_tar_inc; + ap_addr_2_tile(&tile, &addr); + rc = coresight_write(tile, addr, data); + if (!rc && (ap_csw & CSW_ADDRINC_MASK)) + ap_tar_inc += (ap_csw & 0x03) * 2; + break; + + default: + rc = EINVAL; + break; + } + + /* Track the last error code. */ + if (rc != ERROR_OK) + rshim_dap_retval = rc; + + return rc; +} + +static int rshim_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack) +{ + return ERROR_OK; +} + +static int rshim_dp_run(struct adiv5_dap *dap) +{ + int retval = rshim_dap_retval; + + /* Clear the error code. */ + rshim_dap_retval = ERROR_OK; + + return retval; +} + +static int rshim_connect(struct adiv5_dap *dap) +{ + char *path = rshim_dev_path ? rshim_dev_path : RSHIM_DEV_PATH_DEFAULT; + + rshim_fd = open(path, O_RDWR | O_SYNC); + if (rshim_fd == -1) { + LOG_ERROR("Unable to open %s\n", path); + return ERROR_FAIL; + } + + /* + * Set read/write operation via the device file. Funtion pointers + * are used here so more ways like remote accessing via socket could + * be added later. + */ + rshim_read = rshim_dev_read; + rshim_write = rshim_dev_write; + + return ERROR_OK; +} + +static void rshim_disconnect(struct adiv5_dap *dap) +{ + if (rshim_fd != -1) { + close(rshim_fd); + rshim_fd = -1; + } +} + +COMMAND_HANDLER(rshim_dap_device_command) +{ + if (CMD_ARGC != 1) { + command_print(CMD, "Too many arguments"); + return ERROR_COMMAND_SYNTAX_ERROR; + } + + free(rshim_dev_path); + rshim_dev_path = strdup(CMD_ARGV[0]); + return ERROR_OK; +} + +static const struct command_registration rshim_dap_subcommand_handlers[] = { + { + .name = "device", + .handler = rshim_dap_device_command, + .mode = COMMAND_CONFIG, + .help = "set the rshim device", + .usage = "/rshim>", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration rshim_dap_command_handlers[] = { + { + .name = "rshim", + .mode = COMMAND_ANY, + .help = "perform rshim management", + .chain = rshim_dap_subcommand_handlers, + .usage = "", + }, + COMMAND_REGISTRATION_DONE +}; + +static int rshim_dap_init(void) +{ + return ERROR_OK; +} + +static int rshim_dap_quit(void) +{ + return ERROR_OK; +} + +static int rshim_dap_reset(int req_trst, int req_srst) +{ + return ERROR_OK; +} + +static int rshim_dap_speed(int speed) +{ + return ERROR_OK; +} + +static int rshim_dap_khz(int khz, int *jtag_speed) +{ + *jtag_speed = khz; + return ERROR_OK; +} + +static int rshim_dap_speed_div(int speed, int *khz) +{ + *khz = speed; + return ERROR_OK; +} + +/* DAP operations. */ +static const struct dap_ops rshim_dap_ops = { + .connect = rshim_connect, + .queue_dp_read = rshim_dp_q_read, + .queue_dp_write = rshim_dp_q_write, + .queue_ap_read = rshim_ap_q_read, + .queue_ap_write = rshim_ap_q_write, + .queue_ap_abort = rshim_ap_q_abort, + .run = rshim_dp_run, + .quit = rshim_disconnect, +}; + +static const char *const rshim_dap_transport[] = { "dapdirect_swd", NULL }; + +struct adapter_driver rshim_dap_adapter_driver = { + .name = "rshim", + .transports = rshim_dap_transport, + .commands = rshim_dap_command_handlers, + + .init = rshim_dap_init, + .quit = rshim_dap_quit, + .reset = rshim_dap_reset, + .speed = rshim_dap_speed, + .khz = rshim_dap_khz, + .speed_div = rshim_dap_speed_div, + + .dap_swd_ops = &rshim_dap_ops, +}; diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index 00b3bb502..25858ea73 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -141,6 +141,9 @@ extern struct adapter_driver xds110_adapter_driver; #if BUILD_HLADAPTER == 1 extern struct adapter_driver stlink_dap_adapter_driver; #endif +#if BUILD_RSHIM == 1 +extern struct adapter_driver rshim_dap_adapter_driver; +#endif #endif /* standard drivers */ /** @@ -252,6 +255,9 @@ struct adapter_driver *adapter_drivers[] = { #if BUILD_HLADAPTER == 1 &stlink_dap_adapter_driver, #endif +#if BUILD_RSHIM == 1 + &rshim_dap_adapter_driver, +#endif #endif /* standard drivers */ NULL, }; diff --git a/tcl/board/bluefield.cfg b/tcl/board/bluefield.cfg new file mode 100644 index 000000000..3058d48ca --- /dev/null +++ b/tcl/board/bluefield.cfg @@ -0,0 +1,6 @@ +# +# Board configuration for BlueField SoC. +# + +source [find interface/rshim.cfg] +source [find target/bluefield.cfg] diff --git a/tcl/interface/rshim.cfg b/tcl/interface/rshim.cfg new file mode 100644 index 000000000..accabf534 --- /dev/null +++ b/tcl/interface/rshim.cfg @@ -0,0 +1,6 @@ +# +# BlueField SoC in-circuit debugger/programmer +# + +adapter driver rshim +transport select dapdirect_swd diff --git a/tcl/target/bluefield.cfg b/tcl/target/bluefield.cfg new file mode 100644 index 000000000..b31dfe8d6 --- /dev/null +++ b/tcl/target/bluefield.cfg @@ -0,0 +1,78 @@ +# BlueField SoC Target + +set _CHIPNAME bluefield + +# Specify the target device +#rshim device /dev/rshim0/rshim + +# Main DAP +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + set _DAP_TAPID 0x4ba00477 +} + +adapter speed 1500 + +swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +# Initialize the target name and command variable. +set _TARGETNAME $_CHIPNAME.cpu +set _smp_command "" + +# CTI relative address +set $_TARGETNAME.cti(0) 0xC4020000 +set $_TARGETNAME.cti(1) 0xC4120000 +set $_TARGETNAME.cti(2) 0xC8020000 +set $_TARGETNAME.cti(3) 0xC8120000 +set $_TARGETNAME.cti(4) 0xCC020000 +set $_TARGETNAME.cti(5) 0xCC120000 +set $_TARGETNAME.cti(6) 0xD0020000 +set $_TARGETNAME.cti(7) 0xD0120000 +set $_TARGETNAME.cti(8) 0xD4020000 +set $_TARGETNAME.cti(9) 0xD4120000 +set $_TARGETNAME.cti(10) 0xD8020000 +set $_TARGETNAME.cti(11) 0xD8120000 +set $_TARGETNAME.cti(12) 0xDC020000 +set $_TARGETNAME.cti(13) 0xDC120000 +set $_TARGETNAME.cti(14) 0xE0020000 +set $_TARGETNAME.cti(15) 0xE0120000 + +# Create debug targets for a number of cores starting from core '_core_start'. +# Adjust the numbers according to board configuration. +set _core_start 0 +set _cores 16 + +# Create each core +for { set _core $_core_start } { $_core < $_core_start + $_cores } { incr _core 1 } { + cti create cti$_core -dap $_CHIPNAME.dap -ctibase [set $_TARGETNAME.cti($_core)] -ap-num 0 + + set _command "target create ${_TARGETNAME}$_core aarch64 \ + -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core" + + if { $_core != $_core_start } { + set _smp_command "$_smp_command ${_TARGETNAME}$_core" + } else { + set _smp_command "target smp ${_TARGETNAME}$_core" + } + + eval $_command +} + +# Configure SMP +if { $_cores > 1 } { + eval $_smp_command +} + +# Make sure the default target is the boot core +targets ${_TARGETNAME}0 + +proc core_up { args } { + global _TARGETNAME + + # Examine remaining cores + foreach _core [set args] { + ${_TARGETNAME}$_core arp_examine + } +} From 5c8de6a7253641bf1e4789bdc3b1e89ab741b1d1 Mon Sep 17 00:00:00 2001 From: Liming Sun Date: Fri, 3 Apr 2020 22:51:13 -0400 Subject: [PATCH 258/354] jtag/drivers/rshim: Disable the driver by default This is a follow-up change of commit 6d6a69d5 to disable it by default. The driver was introduced in 6d6a69d5 and enabled by default in order to run the jenkins build. Signed-off-by: Liming Sun Change-Id: I5c5fc6711b971b65dd5846a6163025879044ec40 Reviewed-on: http://openocd.zylin.com/5563 Tested-by: jenkins Reviewed-by: Antonio Borneo --- configure.ac | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 9c2f1d7ea..1c921fb1c 100644 --- a/configure.ac +++ b/configure.ac @@ -222,11 +222,9 @@ AC_ARG_ENABLE([dummy], AS_HELP_STRING([--enable-dummy], [Enable building the dummy port driver]), [build_dummy=$enableval], [build_dummy=no]) -AS_CASE([$host_os], [linux*], [host_os_linux=yes], [host_os_linux=no]) - AC_ARG_ENABLE([rshim], AS_HELP_STRING([--enable-rshim], [Enable building the rshim driver]), - [build_rshim=$enableval], [build_rshim=$host_os_linux]) + [build_rshim=$enableval], [build_rshim=no]) m4_define([AC_ARG_ADAPTERS], [ m4_foreach([adapter], [$1], From 5c6e32612df3360abe0ada4e434783b5636643f2 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 17 Jun 2019 15:46:11 -0700 Subject: [PATCH 259/354] Remove BUILD_TARGET64 BUILD_TARGET64 creates a larger test matrix and mostly gates the building of the aarch64/armv8 target, make that unconditional, which would help fixing any issues with 64-bit address types anyway. Rebased by Antonio Borneo after commit 1fbe8450a9dd ("mips: Add MIPS64 support") Change-Id: I219f62b744d540d9dde9a42e6b63fd7d91df3dbb Suggested-by: Matthias Welwarsky Signed-off-by: Florian Fainelli Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5240 Tested-by: jenkins --- configure.ac | 12 ------------ src/helper/types.h | 10 ---------- src/target/Makefile.am | 9 +++------ src/target/armv7a_mmu.c | 6 ------ src/target/mips64.c | 4 ---- src/target/mips64_pracc.c | 4 ---- src/target/mips_ejtag.c | 7 ------- src/target/mips_mips64.c | 4 ---- src/target/riscv/riscv-013.c | 6 ------ src/target/target.c | 2 -- 10 files changed, 3 insertions(+), 61 deletions(-) diff --git a/configure.ac b/configure.ac index 1c921fb1c..a6bda8856 100644 --- a/configure.ac +++ b/configure.ac @@ -360,10 +360,6 @@ AC_ARG_ENABLE([internal-libjaylink], [Disable building internal libjaylink]), [use_internal_libjaylink=$enableval], [use_internal_libjaylink=yes]) -AC_ARG_ENABLE([target64], - AS_HELP_STRING([--disable-target64], [Disable 64-bit target address]), - [build_target64=$enableval], [build_target64=yes]) - build_minidriver=no AC_MSG_CHECKING([whether to enable ZY1000 minidriver]) AS_IF([test "x$build_zy1000" = "xyes"], [ @@ -617,13 +613,6 @@ AS_IF([test "x$build_xlnx_pcie_xvc" = "xyes"], [ AC_DEFINE([BUILD_XLNX_PCIE_XVC], [0], [0 if you don't want Xilinx XVC/PCIe driver.]) ]) -AS_IF([test "x$build_target64" = "xyes"], [ - AC_DEFINE([BUILD_TARGET64], [1], [1 if you want 64-bit addresses.]) -], [ - AC_DEFINE([BUILD_TARGET64], [0], [0 if you don't want 64-bit addresses.]) -]) - - PKG_CHECK_MODULES([LIBUSB1], [libusb-1.0], [ use_libusb1=yes AC_DEFINE([HAVE_LIBUSB1], [1], [Define if you have libusb-1.x]) @@ -746,7 +735,6 @@ AM_CONDITIONAL([BITQ], [test "x$build_bitq" = "xyes"]) AM_CONDITIONAL([USE_LIBFTDI], [test "x$use_libftdi" = "xyes"]) AM_CONDITIONAL([USE_HIDAPI], [test "x$use_hidapi" = "xyes"]) AM_CONDITIONAL([USE_LIBJAYLINK], [test "x$use_libjaylink" = "xyes"]) -AM_CONDITIONAL([TARGET64], [test "x$build_target64" = "xyes"]) AM_CONDITIONAL([RSHIM], [test "x$build_rshim" = "xyes"]) AM_CONDITIONAL([MINIDRIVER], [test "x$build_minidriver" = "xyes"]) diff --git a/src/helper/types.h b/src/helper/types.h index b6747f8d4..f3d5e04a3 100644 --- a/src/helper/types.h +++ b/src/helper/types.h @@ -349,7 +349,6 @@ typedef uint64_t uintmax_t; #endif -#if BUILD_TARGET64 typedef uint64_t target_addr_t; #define TARGET_ADDR_MAX UINT64_MAX #define TARGET_PRIdADDR PRId64 @@ -357,15 +356,6 @@ typedef uint64_t target_addr_t; #define TARGET_PRIoADDR PRIo64 #define TARGET_PRIxADDR PRIx64 #define TARGET_PRIXADDR PRIX64 -#else -typedef uint32_t target_addr_t; -#define TARGET_ADDR_MAX UINT32_MAX -#define TARGET_PRIdADDR PRId32 -#define TARGET_PRIuADDR PRIu32 -#define TARGET_PRIoADDR PRIo32 -#define TARGET_PRIxADDR PRIx32 -#define TARGET_PRIXADDR PRIX32 -#endif #define TARGET_ADDR_FMT "0x%8.8" TARGET_PRIxADDR #endif /* OPENOCD_HELPER_TYPES_H */ diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 30d2339bf..42d809d01 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -29,12 +29,9 @@ noinst_LTLIBRARIES += %D%/libtarget.la %D%/dsp563xx.c \ %D%/dsp563xx_once.c \ %D%/dsp5680xx.c \ - %D%/hla_target.c - -if TARGET64 -%C%_libtarget_la_SOURCES +=$(ARMV8_SRC) -%C%_libtarget_la_SOURCES +=$(MIPS64_SRC) -endif + %D%/hla_target.c \ + $(ARMV8_SRC) \ + $(MIPS64_SRC) TARGET_CORE_SRC = \ %D%/algorithm.c \ diff --git a/src/target/armv7a_mmu.c b/src/target/armv7a_mmu.c index f83228d55..eec14a36f 100644 --- a/src/target/armv7a_mmu.c +++ b/src/target/armv7a_mmu.c @@ -62,12 +62,6 @@ int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va, /* decode memory attribute */ SS = (value >> 1) & 1; -#if !BUILD_TARGET64 - if (SS) { - LOG_ERROR("Super section found with no-64 bit address support"); - return ERROR_FAIL; - } -#endif NOS = (value >> 10) & 1; /* Not Outer shareable */ NS = (value >> 9) & 1; /* Non secure */ INNER = (value >> 4) & 0x7; diff --git a/src/target/mips64.c b/src/target/mips64.c index f65aec114..6a7c4252b 100644 --- a/src/target/mips64.c +++ b/src/target/mips64.c @@ -18,8 +18,6 @@ #include "config.h" #endif -#if BUILD_TARGET64 == 1 - #include "mips64.h" static const struct { @@ -623,5 +621,3 @@ int mips64_enable_interrupts(struct target *target, bool enable) return ERROR_OK; } - -#endif /* BUILD_TARGET64 */ diff --git a/src/target/mips64_pracc.c b/src/target/mips64_pracc.c index 57addc72a..b19fd044e 100644 --- a/src/target/mips64_pracc.c +++ b/src/target/mips64_pracc.c @@ -17,8 +17,6 @@ #include "config.h" #endif -#if BUILD_TARGET64 == 1 - #include "mips64.h" #include "mips64_pracc.h" @@ -1427,5 +1425,3 @@ int mips64_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, return retval; } - -#endif /* BUILD_TARGET64 */ diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c index 00bafd033..3735cbb67 100644 --- a/src/target/mips_ejtag.c +++ b/src/target/mips_ejtag.c @@ -27,11 +27,8 @@ #include "mips32.h" #include "mips_ejtag.h" #include "mips32_dmaacc.h" - -#if BUILD_TARGET64 == 1 #include "mips64.h" #include "mips64_pracc.h" -#endif void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr) { @@ -458,8 +455,6 @@ int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_ return ERROR_OK; } -#if BUILD_TARGET64 == 1 - int mips64_ejtag_config_step(struct mips_ejtag *ejtag_info, bool enable_step) { const uint32_t code_enable[] = { @@ -564,5 +559,3 @@ int mips64_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, bool write_t, uint return ERROR_OK; } - -#endif /* BUILD_TARGET64 */ diff --git a/src/target/mips_mips64.c b/src/target/mips_mips64.c index d91700dfe..3a592f7f3 100644 --- a/src/target/mips_mips64.c +++ b/src/target/mips_mips64.c @@ -16,8 +16,6 @@ #include "config.h" #endif -#if BUILD_TARGET64 == 1 - #include "breakpoints.h" #include "mips32.h" #include "mips64.h" @@ -1193,5 +1191,3 @@ struct target_type mips_mips64_target = { .commands = mips64_commands_handlers, }; - -#endif /* BUILD_TARGET64 */ diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 66218b76e..8307b0224 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -1892,11 +1892,9 @@ static target_addr_t sb_read_address(struct target *target) target_addr_t address = 0; uint32_t v; if (sbasize > 32) { -#if BUILD_TARGET64 dmi_read(target, &v, DMI_SBADDRESS1); address |= v; address <<= 32; -#endif } dmi_read(target, &v, DMI_SBADDRESS0); address |= v; @@ -1913,11 +1911,7 @@ static int sb_write_address(struct target *target, target_addr_t address) if (sbasize > 64) dmi_write(target, DMI_SBADDRESS2, 0); if (sbasize > 32) -#if BUILD_TARGET64 dmi_write(target, DMI_SBADDRESS1, address >> 32); -#else - dmi_write(target, DMI_SBADDRESS1, 0); -#endif return dmi_write(target, DMI_SBADDRESS0, address); } diff --git a/src/target/target.c b/src/target/target.c index 24fa416f8..538831b5b 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -148,10 +148,8 @@ static struct target_type *target_types[] = { &mem_ap_target, &esirisc_target, &arcv2_target, -#if BUILD_TARGET64 &aarch64_target, &mips_mips64_target, -#endif NULL, }; From 65d8fdf0d1e7aa931dd70cb2b0784473fe7834e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Martin?= Date: Tue, 23 Jul 2019 21:21:39 +0200 Subject: [PATCH 260/354] nrf5: Include generated loader code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dump legacy hexadecimal machine code Change-Id: I336efa461058bccc3894131cb22473785b68479c Signed-off-by: Aurélien Martin Reviewed-on: http://openocd.zylin.com/5267 Tested-by: jenkins Reviewed-by: Tomas Vanek --- contrib/loaders/flash/nrf5/Makefile | 28 +++++++++++++++ contrib/loaders/flash/nrf5/nrf5.S | 55 +++++++++++++++++++++++++++++ contrib/loaders/flash/nrf5/nrf5.inc | 3 ++ src/flash/nor/nrf5.c | 28 +++------------ 4 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 contrib/loaders/flash/nrf5/Makefile create mode 100644 contrib/loaders/flash/nrf5/nrf5.S create mode 100644 contrib/loaders/flash/nrf5/nrf5.inc diff --git a/contrib/loaders/flash/nrf5/Makefile b/contrib/loaders/flash/nrf5/Makefile new file mode 100644 index 000000000..67390b9bd --- /dev/null +++ b/contrib/loaders/flash/nrf5/Makefile @@ -0,0 +1,28 @@ +BIN2C = ../../../../src/helper/bin2char.sh + +CROSS_COMPILE ?= arm-none-eabi- + +CC=$(CROSS_COMPILE)gcc +OBJCOPY=$(CROSS_COMPILE)objcopy +OBJDUMP=$(CROSS_COMPILE)objdump + +CFLAGS = -static -nostartfiles -mlittle-endian -Wa,-EL + +all: nrf5.inc + +.PHONY: clean + +%.elf: %.S + $(CC) $(CFLAGS) $< -o $@ + +%.lst: %.elf + $(OBJDUMP) -S $< > $@ + +%.bin: %.elf + $(OBJCOPY) -Obinary $< $@ + +%.inc: %.bin + $(BIN2C) < $< > $@ + +clean: + -rm -f *.elf *.lst *.bin *.inc diff --git a/contrib/loaders/flash/nrf5/nrf5.S b/contrib/loaders/flash/nrf5/nrf5.S new file mode 100644 index 000000000..b148e3caf --- /dev/null +++ b/contrib/loaders/flash/nrf5/nrf5.S @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2014 Angus Gratton * + * gus@projectgus.com * + * * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc. * + ***************************************************************************/ + + .text + .syntax unified + .thumb + +/* + * Params : + * r0 = byte count + * r1 = buffer start + * r2 = buffer end + * r3 = target address + */ + + .thumb_func + .global _start +_start: +wait_fifo: + ldr r5, [r1, #0] + cmp r5, #0 + beq.n exit + ldr r4, [r1, #4] + cmp r4, r5 + beq.n wait_fifo + ldmia r4!, {r5} + stmia r3!, {r5} + cmp r4, r2 + bcc.n no_wrap + mov r4, r1 + adds r4, #8 +no_wrap: + str r4, [r1, #4] + subs r0, #4 + bne.n wait_fifo +exit: + bkpt #0x00 + + .pool diff --git a/contrib/loaders/flash/nrf5/nrf5.inc b/contrib/loaders/flash/nrf5/nrf5.inc new file mode 100644 index 000000000..a9b185c45 --- /dev/null +++ b/contrib/loaders/flash/nrf5/nrf5.inc @@ -0,0 +1,3 @@ +/* Autogenerated with ../../../../src/helper/bin2char.sh */ +0x0d,0x68,0x00,0x2d,0x0b,0xd0,0x4c,0x68,0xac,0x42,0xf9,0xd0,0x20,0xcc,0x20,0xc3, +0x94,0x42,0x01,0xd3,0x0c,0x46,0x08,0x34,0x4c,0x60,0x04,0x38,0xf0,0xd1,0x00,0xbe, diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index 5bef8487c..c569c1800 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -900,30 +900,6 @@ static int nrf5_erase_page(struct flash_bank *bank, return res; } -static const uint8_t nrf5_flash_write_code[] = { - /* See contrib/loaders/flash/cortex-m0.S */ -/* : */ - 0x0d, 0x68, /* ldr r5, [r1, #0] */ - 0x00, 0x2d, /* cmp r5, #0 */ - 0x0b, 0xd0, /* beq.n 1e */ - 0x4c, 0x68, /* ldr r4, [r1, #4] */ - 0xac, 0x42, /* cmp r4, r5 */ - 0xf9, 0xd0, /* beq.n 0 */ - 0x20, 0xcc, /* ldmia r4!, {r5} */ - 0x20, 0xc3, /* stmia r3!, {r5} */ - 0x94, 0x42, /* cmp r4, r2 */ - 0x01, 0xd3, /* bcc.n 18 */ - 0x0c, 0x46, /* mov r4, r1 */ - 0x08, 0x34, /* adds r4, #8 */ -/* : */ - 0x4c, 0x60, /* str r4, [r1, #4] */ - 0x04, 0x38, /* subs r0, #4 */ - 0xf0, 0xd1, /* bne.n 0 */ -/* : */ - 0x00, 0xbe /* bkpt 0x0000 */ -}; - - /* Start a low level flash write for the specified region */ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const uint8_t *buffer, uint32_t bytes) { @@ -935,6 +911,10 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const u struct armv7m_algorithm armv7m_info; int retval = ERROR_OK; + static const uint8_t nrf5_flash_write_code[] = { +#include "../../../contrib/loaders/flash/nrf5/nrf5.inc" + }; + LOG_DEBUG("Writing buffer to flash address=0x%"PRIx32" bytes=0x%"PRIx32, address, bytes); assert(bytes % 4 == 0); From 3c8aa12859e909b4d14162bd7578bf84571bac20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Martin?= Date: Mon, 22 Jul 2019 23:13:29 +0200 Subject: [PATCH 261/354] nrf5: Refresh the watchdog while flashing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If watchdog is enabled, there's no way we can disable it while the flashing firmware is running. (Halt disables it, but software reset doesn't.) So let's have the flashing firmware refresh the watchdog regularly, in case it has been enabled by previously running software. Failure to do so could lead to a watchdog reset in the middle of the chip bieng programmed. Change-Id: I79d41593948aae0080480e891552e1c2ee3ccbd0 Signed-off-by: Aurélien Martin Reviewed-on: http://openocd.zylin.com/5266 Tested-by: jenkins Reviewed-by: Tomas Vanek --- contrib/loaders/flash/nrf5/nrf5.S | 3 +++ contrib/loaders/flash/nrf5/nrf5.inc | 5 +++-- src/flash/nor/nrf5.c | 14 ++++++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/contrib/loaders/flash/nrf5/nrf5.S b/contrib/loaders/flash/nrf5/nrf5.S index b148e3caf..6f7ed9ae7 100644 --- a/contrib/loaders/flash/nrf5/nrf5.S +++ b/contrib/loaders/flash/nrf5/nrf5.S @@ -27,12 +27,15 @@ * r1 = buffer start * r2 = buffer end * r3 = target address + * r6 = watchdog refresh value + * r7 = watchdog refresh register address */ .thumb_func .global _start _start: wait_fifo: + str r6, [r7, #0] ldr r5, [r1, #0] cmp r5, #0 beq.n exit diff --git a/contrib/loaders/flash/nrf5/nrf5.inc b/contrib/loaders/flash/nrf5/nrf5.inc index a9b185c45..2b35b5d6d 100644 --- a/contrib/loaders/flash/nrf5/nrf5.inc +++ b/contrib/loaders/flash/nrf5/nrf5.inc @@ -1,3 +1,4 @@ /* Autogenerated with ../../../../src/helper/bin2char.sh */ -0x0d,0x68,0x00,0x2d,0x0b,0xd0,0x4c,0x68,0xac,0x42,0xf9,0xd0,0x20,0xcc,0x20,0xc3, -0x94,0x42,0x01,0xd3,0x0c,0x46,0x08,0x34,0x4c,0x60,0x04,0x38,0xf0,0xd1,0x00,0xbe, +0x3e,0x60,0x0d,0x68,0x00,0x2d,0x0b,0xd0,0x4c,0x68,0xac,0x42,0xf8,0xd0,0x20,0xcc, +0x20,0xc3,0x94,0x42,0x01,0xd3,0x0c,0x46,0x08,0x34,0x4c,0x60,0x04,0x38,0xef,0xd1, +0x00,0xbe, diff --git a/src/flash/nor/nrf5.c b/src/flash/nor/nrf5.c index c569c1800..fa67e2bf3 100644 --- a/src/flash/nor/nrf5.c +++ b/src/flash/nor/nrf5.c @@ -28,6 +28,10 @@ #include #include +/* Both those values are constant across the current spectrum ofr nRF5 devices */ +#define WATCHDOG_REFRESH_REGISTER 0x40010600 +#define WATCHDOG_REFRESH_VALUE 0x6e524635 + enum { NRF5_FLASH_BASE = 0x00000000, }; @@ -907,7 +911,7 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const u uint32_t buffer_size = 8192; struct working_area *write_algorithm; struct working_area *source; - struct reg_param reg_params[4]; + struct reg_param reg_params[6]; struct armv7m_algorithm armv7m_info; int retval = ERROR_OK; @@ -965,15 +969,19 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const u init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer start */ init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer end */ init_reg_param(®_params[3], "r3", 32, PARAM_IN_OUT); /* target address */ + init_reg_param(®_params[4], "r6", 32, PARAM_OUT); /* watchdog refresh value */ + init_reg_param(®_params[5], "r7", 32, PARAM_OUT); /* watchdog refresh register address */ buf_set_u32(reg_params[0].value, 0, 32, bytes); buf_set_u32(reg_params[1].value, 0, 32, source->address); buf_set_u32(reg_params[2].value, 0, 32, source->address + source->size); buf_set_u32(reg_params[3].value, 0, 32, address); + buf_set_u32(reg_params[4].value, 0, 32, WATCHDOG_REFRESH_VALUE); + buf_set_u32(reg_params[5].value, 0, 32, WATCHDOG_REFRESH_REGISTER); retval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4, 0, NULL, - 4, reg_params, + ARRAY_SIZE(reg_params), reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info); @@ -985,6 +993,8 @@ static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const u destroy_reg_param(®_params[1]); destroy_reg_param(®_params[2]); destroy_reg_param(®_params[3]); + destroy_reg_param(®_params[4]); + destroy_reg_param(®_params[5]); return retval; } From ec16e522bf6518f38e8923ed4f271bc9bb23c409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Martin?= Date: Tue, 6 Aug 2019 22:08:18 +0200 Subject: [PATCH 262/354] nrf5: Comment the flash loader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia84b5b8ede53f59299a02dc6163d6bbaa31e0fbd Signed-off-by: Aurélien Martin Reviewed-on: http://openocd.zylin.com/5272 Tested-by: jenkins Reviewed-by: Tomas Vanek --- contrib/loaders/flash/nrf5/nrf5.S | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/contrib/loaders/flash/nrf5/nrf5.S b/contrib/loaders/flash/nrf5/nrf5.S index 6f7ed9ae7..53551a2c2 100644 --- a/contrib/loaders/flash/nrf5/nrf5.S +++ b/contrib/loaders/flash/nrf5/nrf5.S @@ -35,24 +35,35 @@ .global _start _start: wait_fifo: + // Kick the watchdog str r6, [r7, #0] + // Load write pointer ldr r5, [r1, #0] + // Abort if it is NULL cmp r5, #0 beq.n exit + // Load read pointer ldr r4, [r1, #4] + // Continue waiting if it equals the write pointer cmp r4, r5 beq.n wait_fifo + // Copy one word from buffer to target, and increment pointers ldmia r4!, {r5} stmia r3!, {r5} + // If at end of buffer, wrap back to buffer start cmp r4, r2 bcc.n no_wrap mov r4, r1 adds r4, #8 no_wrap: + // Update read pointer inside the buffer str r4, [r1, #4] + // Deduce the word transferred from the byte count subs r0, #4 + // Start again bne.n wait_fifo exit: + // Wait for OpenOCD bkpt #0x00 .pool From 73a5f58adba73306b08b7bb22ff8a9511e79869f Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Fri, 1 Mar 2019 13:35:31 +0100 Subject: [PATCH 263/354] tcl/target/nrf52.cfg: detect AP lock and add command to recover Change-Id: I8d2e29ed88a957d412473255e42b022a00dfb9cb Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4984 Tested-by: jenkins --- tcl/target/nrf52.cfg | 75 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/tcl/target/nrf52.cfg b/tcl/target/nrf52.cfg index 00901bf8a..88f2c6912 100644 --- a/tcl/target/nrf52.cfg +++ b/tcl/target/nrf52.cfg @@ -34,9 +34,82 @@ adapter speed 1000 $_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -if { ![using_hla] } { +if { [using_hla] } { + echo "" + echo "nRF52 device has a CTRL-AP dedicated to recover the device from AP lock." + echo "A high level adapter (like a ST-Link) you are currently using cannot access" + echo "the CTRL-AP so 'nrf52_recover' command will not work." + echo "Do not enable UICR APPROTECT." + echo "" +} else { cortex_m reset_config sysresetreq + + $_TARGETNAME configure -event examine-fail nrf52_check_ap_lock } flash bank $_CHIPNAME.flash nrf5 0x00000000 0 1 1 $_TARGETNAME flash bank $_CHIPNAME.uicr nrf5 0x10001000 0 1 1 $_TARGETNAME + +# Test if MEM-AP is locked by UICR APPROTECT +proc nrf52_check_ap_lock {} { + set dap [[target current] cget -dap] + set err [catch {set APPROTECTSTATUS [ocd_$dap apreg 1 0xc]}] + if {$err == 0 && $APPROTECTSTATUS != 1} { + echo "****** WARNING ******" + echo "nRF52 device has AP lock engaged (see UICR APPROTECT register)." + echo "Debug access is denied." + echo "Use 'nrf52_recover' to erase and unlock the device." + echo "" + poll off + } +} + +# Mass erase and unlock the device using proprietary nRF CTRL-AP (AP #1) +# http://www.ebyte.com produces modules with nRF52 locked by default, +# use nrf52_recover to enable flashing and debug. +proc nrf52_recover {} { + set target [target current] + set dap [$target cget -dap] + + set IDR [ocd_$dap apreg 1 0xfc] + if {$IDR != 0x02880000} { + echo "Error: Cannot access nRF52 CTRL-AP!" + return + } + + poll off + + # Assert reset + $dap apreg 1 0 1 + + # Reset ERASEALLSTATUS event + $dap apreg 1 8 0 + + # Trigger ERASEALL task + $dap apreg 1 4 0 + $dap apreg 1 4 1 + + for {set i 0} {1} {incr i} { + set ERASEALLSTATUS [ocd_$dap apreg 1 8] + if {$ERASEALLSTATUS == 1} { + echo "$target device has been successfully erased and unlocked." + break + } + if {$i >= 5} { + echo "Error: $target recovery failed." + break + } + sleep 100 + } + + # Deassert reset + $dap apreg 1 0 0 + + if {$ERASEALLSTATUS == 1} { + sleep 100 + $target arp_examine + poll on + } +} + +add_help_text nrf52_recover "Mass erase and unlock nRF52 device" From 6e86ad6166407ca993a8fd37e05269297d470796 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Thu, 22 Nov 2018 19:05:04 +0100 Subject: [PATCH 264/354] flash/nor: add flash mdw/h/b commands Some flash banks are not mapped in the target memory (e.g. SPI flash, some special pages). Add flash version of mdw/h/b which reads data using the flash driver. Change-Id: I66910e0a69cf523fe5ca1ed6ce7b9e8e176aef4a Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4776 Tested-by: jenkins Reviewed-by: Andreas Bolsch Reviewed-by: Antonio Borneo --- doc/openocd.texi | 13 +++++++ src/flash/nor/tcl.c | 82 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/doc/openocd.texi b/doc/openocd.texi index 35a41d4de..2dbe770ad 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5121,6 +5121,19 @@ each block, and the specified length must stay within that bank. @end deffn @comment no current checks for errors if fill blocks touch multiple banks! +@deffn Command {flash mdw} addr [count] +@deffnx Command {flash mdh} addr [count] +@deffnx Command {flash mdb} addr [count] +Display contents of address @var{addr}, as +32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}), +or 8-bit bytes (@command{mdb}). +If @var{count} is specified, displays that many units. +Reads from flash using the flash driver, therefore it enables reading +from a bank not mapped in target address space. +The flash bank to use is inferred from the @var{address} of +each block, and the specified length must stay within that bank. +@end deffn + @deffn Command {flash write_bank} num filename [offset] Write the binary @file{filename} to flash bank @var{num}, starting at @var{offset} bytes from the beginning of the bank. If @var{offset} diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 30c5d4c80..00bfeb18e 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -628,6 +628,67 @@ done: return retval; } +COMMAND_HANDLER(handle_flash_md_command) +{ + int retval; + + if (CMD_ARGC < 1 || CMD_ARGC > 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + target_addr_t address; + COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address); + + uint32_t count = 1; + if (CMD_ARGC == 2) + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count); + + unsigned int wordsize; + switch (CMD_NAME[2]) { + case 'w': + wordsize = 4; + break; + case 'h': + wordsize = 2; + break; + case 'b': + wordsize = 1; + break; + default: + return ERROR_COMMAND_SYNTAX_ERROR; + } + + if (count == 0) + return ERROR_OK; + + struct target *target = get_current_target(CMD_CTX); + struct flash_bank *bank; + retval = get_flash_bank_by_addr(target, address, true, &bank); + if (retval != ERROR_OK) + return retval; + + uint32_t offset = address - bank->base; + uint32_t sizebytes = count * wordsize; + if (offset + sizebytes > bank->size) { + command_print(CMD, "Cannot cross flash bank borders"); + return ERROR_FAIL; + } + + uint8_t *buffer = calloc(count, wordsize); + if (buffer == NULL) { + command_print(CMD, "No memory for flash read buffer"); + return ERROR_FAIL; + } + + retval = flash_driver_read(bank, buffer, offset, sizebytes); + if (retval == ERROR_OK) + target_handle_md_output(CMD, target, address, wordsize, count, buffer); + + free(buffer); + + return retval; +} + + COMMAND_HANDLER(handle_flash_write_bank_command) { uint32_t offset; @@ -1049,6 +1110,27 @@ static const struct command_registration flash_exec_command_handlers[] = { .help = "Fill n bytes with 8-bit value, starting at " "word address. (No autoerase.)", }, + { + .name = "mdb", + .handler = handle_flash_md_command, + .mode = COMMAND_EXEC, + .usage = "address [count]", + .help = "Display bytes from flash.", + }, + { + .name = "mdh", + .handler = handle_flash_md_command, + .mode = COMMAND_EXEC, + .usage = "address [count]", + .help = "Display half-words from flash.", + }, + { + .name = "mdw", + .handler = handle_flash_md_command, + .mode = COMMAND_EXEC, + .usage = "address [count]", + .help = "Display words from flash.", + }, { .name = "write_bank", .handler = handle_flash_write_bank_command, From ff9ee132e52cf90275cfd9debee4c8d73412418e Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sun, 20 Oct 2019 15:03:44 +0200 Subject: [PATCH 265/354] target/armv7m: minor fixes of target algo exit point check Introduce a new ERROR_TARGET_ALGO_EXIT as currently used ERROR_TARGET_TIMEOUT should be reserved for the timeout only. Do not load PC directly from CPU HW as the register value has already been cached. Change-Id: I0d3630da41fd021676789dc12b52545cc0432ba8 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5329 Tested-by: jenkins Reviewed-by: Christopher Head Reviewed-by: Tarek BOCHKATI --- src/target/armv7m.c | 15 ++++++++------- src/target/target.h | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 82d6e6307..837ccc94e 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -462,7 +462,6 @@ int armv7m_wait_algorithm(struct target *target, struct armv7m_common *armv7m = target_to_armv7m(target); struct armv7m_algorithm *armv7m_algorithm_info = arch_info; int retval = ERROR_OK; - uint32_t pc; /* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint * at the exit point */ @@ -484,12 +483,14 @@ int armv7m_wait_algorithm(struct target *target, return ERROR_TARGET_TIMEOUT; } - armv7m->load_core_reg_u32(target, 15, &pc); - if (exit_point && (pc != exit_point)) { - LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" TARGET_PRIxADDR, - pc, - exit_point); - return ERROR_TARGET_TIMEOUT; + if (exit_point) { + /* PC value has been cached in cortex_m_debug_entry() */ + uint32_t pc = buf_get_u32(armv7m->arm.pc->value, 0, 32); + if (pc != exit_point) { + LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" TARGET_PRIxADDR, + pc, exit_point); + return ERROR_TARGET_ALGO_EXIT; + } } /* Read memory values to mem_params[] */ diff --git a/src/target/target.h b/src/target/target.h index ddeb00b57..fc150442d 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -759,6 +759,7 @@ void target_handle_md_output(struct command_invocation *cmd, #define ERROR_TARGET_NOT_RUNNING (-310) #define ERROR_TARGET_NOT_EXAMINED (-311) #define ERROR_TARGET_DUPLICATE_BREAKPOINT (-312) +#define ERROR_TARGET_ALGO_EXIT (-313) extern bool get_target_reset_nag(void); From 86cf8d9fb0e9ef29d69b97d30aa5670814e00a24 Mon Sep 17 00:00:00 2001 From: Kevin Burke Date: Mon, 4 Nov 2019 20:11:06 +0000 Subject: [PATCH 266/354] target/armv8: Add ARM target name on halt status The CPU target name is added to the HALT status message so the user can see which target halted at the designated program counter. Tested on an Ampere eMAG8180 and Quicksilver silicon Change-Id: I51e6f21296c85a822df28c5b7c4068e8ff66f29e Signed-off-by: Kevin Burke Signed-off-by: Daniel Goehring Reviewed-on: http://openocd.zylin.com/5571 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Antonio Borneo --- src/target/armv8.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/target/armv8.c b/src/target/armv8.c index 88b932073..61f11f24a 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -1131,8 +1131,9 @@ int armv8_aarch64_state(struct target *target) return ERROR_FAIL; } - LOG_USER("target halted in %s state due to %s, current mode: %s\n" + LOG_USER("%s halted in %s state due to %s, current mode: %s\n" "cpsr: 0x%8.8" PRIx32 " pc: 0x%" PRIx64 "%s", + target_name(target), armv8_state_strings[arm->core_state], debug_reason_name(target), armv8_mode_name(arm->core_mode), From 38d205ecc5335191214dbd0f714f4561a7b7b746 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Thu, 6 Feb 2020 16:13:25 +0200 Subject: [PATCH 267/354] ftdi: Report an error if no ftdi_vid_pid is specified By default the list of VID/PID is empty so if ftdi_vid_pid is not called then no matches are attempted. The only message is at -d3: Command 'init' failed with error code -100" Check for this condition explicitly to make life easier for people configuring adapters. Change-Id: If0f93370c9e9ddc9700aae7c346c1c6dd319152e Signed-off-by: Leonard Crestez Reviewed-on: http://openocd.zylin.com/5440 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/ftdi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/jtag/drivers/ftdi.c b/src/jtag/drivers/ftdi.c index 121cb469f..f1d28d2fd 100644 --- a/src/jtag/drivers/ftdi.c +++ b/src/jtag/drivers/ftdi.c @@ -647,6 +647,11 @@ static int ftdi_initialize(void) else LOG_DEBUG("ftdi interface using shortest path jtag state transitions"); + if (!ftdi_vid[0] && !ftdi_pid[0]) { + LOG_ERROR("Please specify ftdi_vid_pid"); + return ERROR_JTAG_INIT_FAILED; + } + for (int i = 0; ftdi_vid[i] || ftdi_pid[i]; i++) { mpsse_ctx = mpsse_open(&ftdi_vid[i], &ftdi_pid[i], ftdi_device_desc, ftdi_serial, jtag_usb_get_location(), ftdi_channel); From bed0215573269cd9f85d23eaa15a27ce13a53e87 Mon Sep 17 00:00:00 2001 From: Ilya Kharin Date: Thu, 16 Apr 2020 03:21:30 +0400 Subject: [PATCH 268/354] flash/nor/stm32l4x: cast wrpxxr_mask to uint16_to to print Fix build error on Mac OS X Catalina (10.15.4) caused by formatting stm32l4_info->wrpxxr_mask, which is uint32_t, as uint16_t in the debug log message. Adding casting to uint16_t before substitution because only lower 16 bits are significant for debug purposes. Change-Id: Iddb87cd156dfc84ab1f91cd15a1ddee6b646d412 Signed-off-by: Ilya Kharin Reviewed-on: http://openocd.zylin.com/5590 Tested-by: jenkins Reviewed-by: Andreas Bolsch Reviewed-by: Antonio Borneo --- src/flash/nor/stm32l4x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 2cc378a90..4b7edae5f 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -1038,7 +1038,7 @@ static int stm32l4_probe(struct flash_bank *bank) /* in dual bank mode number of pages is doubled, but extra bit is bank selection */ stm32l4_info->wrpxxr_mask = ((max_pages >> (stm32l4_info->dual_bank_mode ? 1 : 0)) - 1); assert((stm32l4_info->wrpxxr_mask & 0xFFFF0000) == 0); - LOG_DEBUG("WRPxxR mask 0x%04" PRIx16, stm32l4_info->wrpxxr_mask); + LOG_DEBUG("WRPxxR mask 0x%04" PRIx16, (uint16_t)stm32l4_info->wrpxxr_mask); if (bank->sectors) { free(bank->sectors); From c60252ac2b636c4d99b766a574b9df0966151696 Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Fri, 17 Apr 2020 13:49:28 +0200 Subject: [PATCH 269/354] bitbang: Fix FTBFS with GCC 10 GCC 10 defaults to -fno-common which breaks the sharing of bitbang_swd struct between bitbang drivers due to a missing extern. Change-Id: I2b4122f7939cec91a72284006748f99a23548324 Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/5592 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Jonathan McDowell --- src/jtag/drivers/bitbang.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/drivers/bitbang.h b/src/jtag/drivers/bitbang.h index edb779cad..bbbc693df 100644 --- a/src/jtag/drivers/bitbang.h +++ b/src/jtag/drivers/bitbang.h @@ -56,7 +56,7 @@ struct bitbang_interface { void (*swdio_drive)(bool on); }; -const struct swd_driver bitbang_swd; +extern const struct swd_driver bitbang_swd; extern bool swd_mode; From 9e23c9ae3551dc14e15bdfe129fd9e03c6970f33 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 12 May 2019 12:53:56 +0200 Subject: [PATCH 270/354] coding style: tcl: remove empty lines at end of text files Empty lines at end of text files are useless. Remove them. Change-Id: I503cb0a96c7ccb132f4486c206a48831121d7abd Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5171 Tested-by: jenkins --- tcl/bitsbytes.tcl | 2 -- tcl/board/adsp-sc584-ezbrd.cfg | 1 - tcl/board/altera_sockit.cfg | 1 - tcl/board/am3517evm.cfg | 1 - tcl/board/arm_evaluator7t.cfg | 1 - tcl/board/at91cap7a-stk-sdram.cfg | 1 - tcl/board/at91sam9g20-ek.cfg | 1 - tcl/board/atmel_at91sam7s-ek.cfg | 2 -- tcl/board/atmel_sam3u_ek.cfg | 1 - tcl/board/bcm28155_ap.cfg | 1 - tcl/board/colibri.cfg | 4 ---- tcl/board/dm365evm.cfg | 2 -- tcl/board/eir.cfg | 1 - tcl/board/embedded-artists_lpc2478-32.cfg | 1 - tcl/board/glyn_tonga2.cfg | 1 - tcl/board/hitex_lpc1768stick.cfg | 1 - tcl/board/hitex_lpc2929.cfg | 1 - tcl/board/hitex_stm32-performancestick.cfg | 1 - tcl/board/iar_lpc1768.cfg | 1 - tcl/board/icnova_sam9g45_sodimm.cfg | 2 -- tcl/board/keil_mcb1700.cfg | 1 - tcl/board/keil_mcb2140.cfg | 1 - tcl/board/linksys_nslu2.cfg | 1 - tcl/board/microchip_same54_xplained_pro.cfg | 1 - tcl/board/novena-internal-fpga.cfg | 1 - tcl/board/olimex_LPC2378STK.cfg | 1 - tcl/board/olimex_lpc_h2148.cfg | 1 - tcl/board/olimex_sam7_ex256.cfg | 1 - tcl/board/openrd.cfg | 1 - tcl/board/sheevaplug.cfg | 1 - tcl/board/ti_beagleboard_xm.cfg | 1 - tcl/board/ti_beaglebone.cfg | 2 -- tcl/board/ti_blaze.cfg | 1 - tcl/board/ti_pandaboard.cfg | 1 - tcl/board/ti_pandaboard_es.cfg | 1 - tcl/board/topasa900.cfg | 1 - tcl/board/unknown_at91sam9260.cfg | 2 -- tcl/board/uptech_2410.cfg | 2 -- tcl/board/voltcraft_dso-3062c.cfg | 1 - tcl/chip/atmel/at91/aic.tcl | 1 - tcl/chip/atmel/at91/at91sam9263_matrix.cfg | 2 -- tcl/chip/atmel/at91/pmc.tcl | 1 - tcl/chip/atmel/at91/rtt.tcl | 1 - tcl/chip/atmel/at91/usarts.tcl | 3 --- tcl/cpu/arm/arm7tdmi.tcl | 1 - tcl/cpu/arm/arm920.tcl | 1 - tcl/cpu/arm/arm946.tcl | 1 - tcl/cpu/arm/arm966.tcl | 1 - tcl/cpu/arm/cortex_m3.tcl | 1 - tcl/interface/arm-jtag-ew.cfg | 1 - tcl/interface/at91rm9200.cfg | 1 - tcl/interface/buspirate.cfg | 1 - tcl/interface/calao-usb-a9260.cfg | 1 - tcl/interface/chameleon.cfg | 1 - tcl/interface/dummy.cfg | 1 - tcl/interface/ftdi/hitex_lpc1768stick.cfg | 1 - tcl/interface/parport_dlc5.cfg | 1 - tcl/interface/rlink.cfg | 1 - tcl/interface/stlink.cfg | 1 - tcl/interface/vsllink.cfg | 1 - tcl/target/adsp-sc58x.cfg | 1 - tcl/target/amdm37x.cfg | 1 - tcl/target/ar71xx.cfg | 1 - tcl/target/armada370.cfg | 1 - tcl/target/at91sam3ax_8x.cfg | 2 -- tcl/target/at91sam3ax_xx.cfg | 1 - tcl/target/at91sam3u1c.cfg | 2 -- tcl/target/at91sam3u1e.cfg | 2 -- tcl/target/at91sam3u2c.cfg | 2 -- tcl/target/at91sam3u2e.cfg | 2 -- tcl/target/at91sam3u4c.cfg | 2 -- tcl/target/at91sam3u4e.cfg | 2 -- tcl/target/at91sam3uxx.cfg | 1 - tcl/target/at91sam7se512.cfg | 1 - tcl/target/atsamv.cfg | 1 - tcl/target/avr32.cfg | 1 - tcl/target/cs351x.cfg | 1 - tcl/target/dragonite.cfg | 1 - tcl/target/dsp568013.cfg | 1 - tcl/target/dsp568037.cfg | 1 - tcl/target/feroceon.cfg | 1 - tcl/target/hilscher_netx10.cfg | 1 - tcl/target/icepick.cfg | 1 - tcl/target/ixp42x.cfg | 1 - tcl/target/kx.cfg | 1 - tcl/target/readme.txt | 1 - tcl/target/samsung_s3c2440.cfg | 1 - tcl/target/samsung_s3c4510.cfg | 1 - tcl/target/sharp_lh79532.cfg | 2 -- tcl/target/snps_em_sk_fpga.cfg | 1 - tcl/target/stm32f7x.cfg | 1 - tcl/target/str730.cfg | 1 - tcl/target/u8500.cfg | 2 -- tcl/test/syntax1.cfg | 1 - 94 files changed, 116 deletions(-) diff --git a/tcl/bitsbytes.tcl b/tcl/bitsbytes.tcl index 2c4fd2907..52ca83db2 100644 --- a/tcl/bitsbytes.tcl +++ b/tcl/bitsbytes.tcl @@ -57,5 +57,3 @@ proc show_normalize_bitfield { VALUE MSB LSB } { echo [format "((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d " $VALUE $m $mr $LSB $sr $sr] return $sr } - - diff --git a/tcl/board/adsp-sc584-ezbrd.cfg b/tcl/board/adsp-sc584-ezbrd.cfg index 439fe9268..82df381f6 100644 --- a/tcl/board/adsp-sc584-ezbrd.cfg +++ b/tcl/board/adsp-sc584-ezbrd.cfg @@ -28,4 +28,3 @@ transport select swd adapter speed 400 source [find target/adsp-sc58x.cfg] - diff --git a/tcl/board/altera_sockit.cfg b/tcl/board/altera_sockit.cfg index 3fd01be33..eb4c863fa 100644 --- a/tcl/board/altera_sockit.cfg +++ b/tcl/board/altera_sockit.cfg @@ -16,4 +16,3 @@ source [find target/altera_fpgasoc.cfg] #usb_blaster_device_desc "USB-Blaster II" adapter speed 100 - diff --git a/tcl/board/am3517evm.cfg b/tcl/board/am3517evm.cfg index 2bff51246..8d6eba160 100644 --- a/tcl/board/am3517evm.cfg +++ b/tcl/board/am3517evm.cfg @@ -18,4 +18,3 @@ source [find target/amdm37x.cfg] reset_config trst_only # "amdm37x_dbginit am35x.cpu" needs to be run after init. - diff --git a/tcl/board/arm_evaluator7t.cfg b/tcl/board/arm_evaluator7t.cfg index 52de57afe..96d859cd3 100644 --- a/tcl/board/arm_evaluator7t.cfg +++ b/tcl/board/arm_evaluator7t.cfg @@ -7,4 +7,3 @@ source [find target/samsung_s3c4510.cfg] # Add (A) sdram configuration # Add (B) flash cfi programing configuration # - diff --git a/tcl/board/at91cap7a-stk-sdram.cfg b/tcl/board/at91cap7a-stk-sdram.cfg index a0e393f2c..df91a6b0b 100644 --- a/tcl/board/at91cap7a-stk-sdram.cfg +++ b/tcl/board/at91cap7a-stk-sdram.cfg @@ -162,4 +162,3 @@ arm7_9 fast_memory_access enable #set _FLASHNAME $_CHIPNAME.flash #flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432 - diff --git a/tcl/board/at91sam9g20-ek.cfg b/tcl/board/at91sam9g20-ek.cfg index 773c8899a..e8018766a 100644 --- a/tcl/board/at91sam9g20-ek.cfg +++ b/tcl/board/at91sam9g20-ek.cfg @@ -216,4 +216,3 @@ proc at91sam9g20_reset_init { } { mww 0xffffea04 0x0000039c } - diff --git a/tcl/board/atmel_at91sam7s-ek.cfg b/tcl/board/atmel_at91sam7s-ek.cfg index d7e848654..48edfc9a7 100644 --- a/tcl/board/atmel_at91sam7s-ek.cfg +++ b/tcl/board/atmel_at91sam7s-ek.cfg @@ -4,5 +4,3 @@ set CHIPNAME at91sam7s256 source [find target/at91sam7sx.cfg] - - diff --git a/tcl/board/atmel_sam3u_ek.cfg b/tcl/board/atmel_sam3u_ek.cfg index 13d930b1d..1584879bf 100644 --- a/tcl/board/atmel_sam3u_ek.cfg +++ b/tcl/board/atmel_sam3u_ek.cfg @@ -1,4 +1,3 @@ source [find target/at91sam3u4e.cfg] reset_config srst_only - diff --git a/tcl/board/bcm28155_ap.cfg b/tcl/board/bcm28155_ap.cfg index 770ff9cd5..5d3d22a3e 100644 --- a/tcl/board/bcm28155_ap.cfg +++ b/tcl/board/bcm28155_ap.cfg @@ -6,4 +6,3 @@ set CHIPNAME bcm28155 source [find target/bcm281xx.cfg] reset_config trst_and_srst - diff --git a/tcl/board/colibri.cfg b/tcl/board/colibri.cfg index fe9a3d50e..0f30afd09 100644 --- a/tcl/board/colibri.cfg +++ b/tcl/board/colibri.cfg @@ -7,7 +7,3 @@ adapter srst pulse_width 40 # the bank is 32-bits wide, two 16-bit chips in parallel set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME - - - - diff --git a/tcl/board/dm365evm.cfg b/tcl/board/dm365evm.cfg index ed34c4b29..3b29dd866 100644 --- a/tcl/board/dm365evm.cfg +++ b/tcl/board/dm365evm.cfg @@ -143,5 +143,3 @@ proc dm365evm_init {} { flashprobe } - - diff --git a/tcl/board/eir.cfg b/tcl/board/eir.cfg index a014e116b..422db0d88 100644 --- a/tcl/board/eir.cfg +++ b/tcl/board/eir.cfg @@ -91,4 +91,3 @@ $_TARGETNAME configure -event reset-init { # mww 0xfffffd08 0xa5000001 } - diff --git a/tcl/board/embedded-artists_lpc2478-32.cfg b/tcl/board/embedded-artists_lpc2478-32.cfg index 6c3aec648..8ef9179de 100644 --- a/tcl/board/embedded-artists_lpc2478-32.cfg +++ b/tcl/board/embedded-artists_lpc2478-32.cfg @@ -151,4 +151,3 @@ proc enable_pll {} { mww 0xE01FC08C 0x000000AA ;# PLLFEED mww 0xE01FC08C 0x00000055 ;# PLLFEED } - diff --git a/tcl/board/glyn_tonga2.cfg b/tcl/board/glyn_tonga2.cfg index 31aa9ff5e..f48702ca6 100644 --- a/tcl/board/glyn_tonga2.cfg +++ b/tcl/board/glyn_tonga2.cfg @@ -197,4 +197,3 @@ proc tonga2_init { } { ####################### # TODO: Implement NAND support. - diff --git a/tcl/board/hitex_lpc1768stick.cfg b/tcl/board/hitex_lpc1768stick.cfg index 8c1193608..ac176cad7 100644 --- a/tcl/board/hitex_lpc1768stick.cfg +++ b/tcl/board/hitex_lpc1768stick.cfg @@ -12,4 +12,3 @@ source [find target/lpc17xx.cfg] # startup @ 500kHz adapter speed 500 - diff --git a/tcl/board/hitex_lpc2929.cfg b/tcl/board/hitex_lpc2929.cfg index f51779867..2fe1f3cda 100644 --- a/tcl/board/hitex_lpc2929.cfg +++ b/tcl/board/hitex_lpc2929.cfg @@ -103,4 +103,3 @@ $_TARGETNAME configure -event reset-init { mww 0x600000CC 0x0000000C ;# Bank7 WST2=8 mww 0x600000C4 0x00000002 ;# Bank7 IDCY=2 } - diff --git a/tcl/board/hitex_stm32-performancestick.cfg b/tcl/board/hitex_stm32-performancestick.cfg index 738178af0..74dc5839a 100644 --- a/tcl/board/hitex_stm32-performancestick.cfg +++ b/tcl/board/hitex_stm32-performancestick.cfg @@ -13,4 +13,3 @@ jtag newtap str750 cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id 0x4f1f0 # for some reason this board like to startup @ 500kHz adapter speed 500 - diff --git a/tcl/board/iar_lpc1768.cfg b/tcl/board/iar_lpc1768.cfg index d8c8c2d71..38ffc3582 100644 --- a/tcl/board/iar_lpc1768.cfg +++ b/tcl/board/iar_lpc1768.cfg @@ -14,4 +14,3 @@ $_TARGETNAME configure -event reset-init { flash probe 0 } - diff --git a/tcl/board/icnova_sam9g45_sodimm.cfg b/tcl/board/icnova_sam9g45_sodimm.cfg index bf70cca9a..30dc34748 100644 --- a/tcl/board/icnova_sam9g45_sodimm.cfg +++ b/tcl/board/icnova_sam9g45_sodimm.cfg @@ -274,5 +274,3 @@ proc at91sam9g45_init { } { arm7_9 fast_memory_access enable } - - diff --git a/tcl/board/keil_mcb1700.cfg b/tcl/board/keil_mcb1700.cfg index d63d3ede9..05f12dfba 100644 --- a/tcl/board/keil_mcb1700.cfg +++ b/tcl/board/keil_mcb1700.cfg @@ -5,4 +5,3 @@ # source [find target/lpc17xx.cfg] - diff --git a/tcl/board/keil_mcb2140.cfg b/tcl/board/keil_mcb2140.cfg index db81efad5..bb41a2ab5 100644 --- a/tcl/board/keil_mcb2140.cfg +++ b/tcl/board/keil_mcb2140.cfg @@ -5,4 +5,3 @@ # source [find target/lpc2148.cfg] - diff --git a/tcl/board/linksys_nslu2.cfg b/tcl/board/linksys_nslu2.cfg index e605fc19e..0b0f58b84 100644 --- a/tcl/board/linksys_nslu2.cfg +++ b/tcl/board/linksys_nslu2.cfg @@ -5,4 +5,3 @@ source [find target/ixp42x.cfg] # The _TARGETNAME is set by the above. $_TARGETNAME configure -work-area-phys 0x00020000 -work-area-size 0x10000 -work-area-backup 0 - diff --git a/tcl/board/microchip_same54_xplained_pro.cfg b/tcl/board/microchip_same54_xplained_pro.cfg index db8a8561d..7482de47f 100644 --- a/tcl/board/microchip_same54_xplained_pro.cfg +++ b/tcl/board/microchip_same54_xplained_pro.cfg @@ -10,4 +10,3 @@ set CHIPNAME same54 source [find target/atsame5x.cfg] reset_config srst_only - diff --git a/tcl/board/novena-internal-fpga.cfg b/tcl/board/novena-internal-fpga.cfg index 24a76dceb..0e9ff5b1f 100644 --- a/tcl/board/novena-internal-fpga.cfg +++ b/tcl/board/novena-internal-fpga.cfg @@ -22,4 +22,3 @@ transport select jtag sysfsgpio_jtag_nums 136 139 137 138 source [find cpld/xilinx-xc6s.cfg] - diff --git a/tcl/board/olimex_LPC2378STK.cfg b/tcl/board/olimex_LPC2378STK.cfg index a4b422dcc..7e9e58e70 100644 --- a/tcl/board/olimex_LPC2378STK.cfg +++ b/tcl/board/olimex_LPC2378STK.cfg @@ -8,4 +8,3 @@ # source [find target/lpc2378.cfg] - diff --git a/tcl/board/olimex_lpc_h2148.cfg b/tcl/board/olimex_lpc_h2148.cfg index 7833fdec6..d8fb5bef9 100644 --- a/tcl/board/olimex_lpc_h2148.cfg +++ b/tcl/board/olimex_lpc_h2148.cfg @@ -5,4 +5,3 @@ # source [find target/lpc2148.cfg] - diff --git a/tcl/board/olimex_sam7_ex256.cfg b/tcl/board/olimex_sam7_ex256.cfg index 5f83629de..426ead6aa 100644 --- a/tcl/board/olimex_sam7_ex256.cfg +++ b/tcl/board/olimex_sam7_ex256.cfg @@ -1,4 +1,3 @@ # Olimex SAM7-EX256 has a single Atmel at91sam7ex256 on it. source [find target/sam7x256.cfg] - diff --git a/tcl/board/openrd.cfg b/tcl/board/openrd.cfg index 696af4e5b..fda01d129 100644 --- a/tcl/board/openrd.cfg +++ b/tcl/board/openrd.cfg @@ -122,4 +122,3 @@ proc openrd_load_uboot { } { resume 0x00600000 } - diff --git a/tcl/board/sheevaplug.cfg b/tcl/board/sheevaplug.cfg index 7ccb88410..455163777 100644 --- a/tcl/board/sheevaplug.cfg +++ b/tcl/board/sheevaplug.cfg @@ -133,4 +133,3 @@ proc sheevaplug_load_uboot { } { resume 0x00600000 } - diff --git a/tcl/board/ti_beagleboard_xm.cfg b/tcl/board/ti_beagleboard_xm.cfg index e4e93e333..683f583b2 100644 --- a/tcl/board/ti_beagleboard_xm.cfg +++ b/tcl/board/ti_beagleboard_xm.cfg @@ -9,4 +9,3 @@ source [find target/amdm37x.cfg] reset_config trst_only # "amdm37x_dbginit dm37x.cpu" needs to be run after init. - diff --git a/tcl/board/ti_beaglebone.cfg b/tcl/board/ti_beaglebone.cfg index 6a6272d2d..7ba8c50f2 100644 --- a/tcl/board/ti_beaglebone.cfg +++ b/tcl/board/ti_beaglebone.cfg @@ -9,5 +9,3 @@ adapter speed 16000 reset_config trst_and_srst source [find board/ti_beaglebone-base.cfg] - - diff --git a/tcl/board/ti_blaze.cfg b/tcl/board/ti_blaze.cfg index c9bbe25c0..488138982 100644 --- a/tcl/board/ti_blaze.cfg +++ b/tcl/board/ti_blaze.cfg @@ -3,4 +3,3 @@ jtag_rclk 6000 source [find target/omap4430.cfg] reset_config trst_and_srst - diff --git a/tcl/board/ti_pandaboard.cfg b/tcl/board/ti_pandaboard.cfg index bd2cd3703..bc9259610 100644 --- a/tcl/board/ti_pandaboard.cfg +++ b/tcl/board/ti_pandaboard.cfg @@ -3,4 +3,3 @@ jtag_rclk 6000 source [find target/omap4430.cfg] reset_config trst_only - diff --git a/tcl/board/ti_pandaboard_es.cfg b/tcl/board/ti_pandaboard_es.cfg index 2abd7e97a..756fa33ee 100644 --- a/tcl/board/ti_pandaboard_es.cfg +++ b/tcl/board/ti_pandaboard_es.cfg @@ -3,4 +3,3 @@ jtag_rclk 6000 source [find target/omap4460.cfg] reset_config trst_only - diff --git a/tcl/board/topasa900.cfg b/tcl/board/topasa900.cfg index 91ee5847a..5bd0e5e02 100644 --- a/tcl/board/topasa900.cfg +++ b/tcl/board/topasa900.cfg @@ -123,4 +123,3 @@ arm7_9 dcc_downloads enable ;# Enable faster DCC downloads #flash bank cfi set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME cfi 0x20000000 0x1000000 2 2 $_TARGETNAME - diff --git a/tcl/board/unknown_at91sam9260.cfg b/tcl/board/unknown_at91sam9260.cfg index de49a69f5..5570ef04b 100644 --- a/tcl/board/unknown_at91sam9260.cfg +++ b/tcl/board/unknown_at91sam9260.cfg @@ -93,5 +93,3 @@ $_TARGETNAME configure -event reset-init { #flash bank cfi set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME - - diff --git a/tcl/board/uptech_2410.cfg b/tcl/board/uptech_2410.cfg index 950f2a7c1..680cfd7d6 100644 --- a/tcl/board/uptech_2410.cfg +++ b/tcl/board/uptech_2410.cfg @@ -61,5 +61,3 @@ proc uptech2410_init { } { set _NANDNAME $_CHIPNAME.nand nand device $_NANDNAME s3c2410 $_TARGETNAME - - diff --git a/tcl/board/voltcraft_dso-3062c.cfg b/tcl/board/voltcraft_dso-3062c.cfg index 01879b128..f300cf2b6 100644 --- a/tcl/board/voltcraft_dso-3062c.cfg +++ b/tcl/board/voltcraft_dso-3062c.cfg @@ -28,4 +28,3 @@ scan_chain targets nand probe 0 nand list - diff --git a/tcl/chip/atmel/at91/aic.tcl b/tcl/chip/atmel/at91/aic.tcl index 6dae36ad6..ba0f2a91b 100644 --- a/tcl/chip/atmel/at91/aic.tcl +++ b/tcl/chip/atmel/at91/aic.tcl @@ -98,4 +98,3 @@ proc show_AIC { } { } } } - diff --git a/tcl/chip/atmel/at91/at91sam9263_matrix.cfg b/tcl/chip/atmel/at91/at91sam9263_matrix.cfg index ad3d9a2a3..f287cd9bf 100644 --- a/tcl/chip/atmel/at91/at91sam9263_matrix.cfg +++ b/tcl/chip/atmel/at91/at91sam9263_matrix.cfg @@ -108,5 +108,3 @@ set AT91_MATRIX_EBI1_DBPUC [expr (1 << 8)] ;# Data Bus Pull-up Configuration set AT91_MATRIX_EBI1_VDDIOMSEL [expr (1 << 16)] ;# Memory voltage selection set AT91_MATRIX_EBI1_VDDIOMSEL_1_8V [expr (0 << 16)] set AT91_MATRIX_EBI1_VDDIOMSEL_3_3V [expr (1 << 16)] - - diff --git a/tcl/chip/atmel/at91/pmc.tcl b/tcl/chip/atmel/at91/pmc.tcl index 584acb80b..7cb1d093e 100644 --- a/tcl/chip/atmel/at91/pmc.tcl +++ b/tcl/chip/atmel/at91/pmc.tcl @@ -14,4 +14,3 @@ if [info exists AT91C_SLOWOSC_FREQ] { set AT91C_SLOWOSC_FREQ 32768 } global AT91C_SLOWOSC_FREQ - diff --git a/tcl/chip/atmel/at91/rtt.tcl b/tcl/chip/atmel/at91/rtt.tcl index 8be6a56b0..2dd74fab9 100644 --- a/tcl/chip/atmel/at91/rtt.tcl +++ b/tcl/chip/atmel/at91/rtt.tcl @@ -53,4 +53,3 @@ proc show_RTTC { } { show_mmr32_reg RTTC_RTVR show_mmr32_reg RTTC_RTSR } - diff --git a/tcl/chip/atmel/at91/usarts.tcl b/tcl/chip/atmel/at91/usarts.tcl index 68420292e..ecc4f6034 100644 --- a/tcl/chip/atmel/at91/usarts.tcl +++ b/tcl/chip/atmel/at91/usarts.tcl @@ -130,6 +130,3 @@ proc show_DBGU { } $str unset str proc show_DBGU_MR_helper { NAME ADDR VAL } { show_mmr_USx_MR_helper $NAME $ADDR $VAL } - - - diff --git a/tcl/cpu/arm/arm7tdmi.tcl b/tcl/cpu/arm/arm7tdmi.tcl index 37db26618..a1d4a1f46 100644 --- a/tcl/cpu/arm/arm7tdmi.tcl +++ b/tcl/cpu/arm/arm7tdmi.tcl @@ -3,4 +3,3 @@ set CPU_NAME arm7tdmi set CPU_ARCH armv4t set CPU_MAX_ADDRESS 0xFFFFFFFF set CPU_NBITS 32 - diff --git a/tcl/cpu/arm/arm920.tcl b/tcl/cpu/arm/arm920.tcl index f19b20b3c..c01f602f2 100644 --- a/tcl/cpu/arm/arm920.tcl +++ b/tcl/cpu/arm/arm920.tcl @@ -3,4 +3,3 @@ set CPU_NAME arm920 set CPU_ARCH armv4t set CPU_MAX_ADDRESS 0xFFFFFFFF set CPU_NBITS 32 - diff --git a/tcl/cpu/arm/arm946.tcl b/tcl/cpu/arm/arm946.tcl index 520410178..a6110a53f 100644 --- a/tcl/cpu/arm/arm946.tcl +++ b/tcl/cpu/arm/arm946.tcl @@ -3,4 +3,3 @@ set CPU_NAME arm946 set CPU_ARCH armv5te set CPU_MAX_ADDRESS 0xFFFFFFFF set CPU_NBITS 32 - diff --git a/tcl/cpu/arm/arm966.tcl b/tcl/cpu/arm/arm966.tcl index 83ce0f673..1fffbc092 100644 --- a/tcl/cpu/arm/arm966.tcl +++ b/tcl/cpu/arm/arm966.tcl @@ -3,4 +3,3 @@ set CPU_NAME arm966 set CPU_ARCH armv5te set CPU_MAX_ADDRESS 0xFFFFFFFF set CPU_NBITS 32 - diff --git a/tcl/cpu/arm/cortex_m3.tcl b/tcl/cpu/arm/cortex_m3.tcl index 166af847d..c9950261f 100644 --- a/tcl/cpu/arm/cortex_m3.tcl +++ b/tcl/cpu/arm/cortex_m3.tcl @@ -3,4 +3,3 @@ set CPU_NAME cortex_m3 set CPU_ARCH armv7 set CPU_MAX_ADDRESS 0xFFFFFFFF set CPU_NBITS 32 - diff --git a/tcl/interface/arm-jtag-ew.cfg b/tcl/interface/arm-jtag-ew.cfg index 250592f20..797bb7121 100644 --- a/tcl/interface/arm-jtag-ew.cfg +++ b/tcl/interface/arm-jtag-ew.cfg @@ -5,4 +5,3 @@ # adapter driver arm-jtag-ew - diff --git a/tcl/interface/at91rm9200.cfg b/tcl/interface/at91rm9200.cfg index 0561dac43..b66e060d1 100644 --- a/tcl/interface/at91rm9200.cfg +++ b/tcl/interface/at91rm9200.cfg @@ -6,4 +6,3 @@ adapter driver at91rm9200 at91rm9200_device rea_ecr - diff --git a/tcl/interface/buspirate.cfg b/tcl/interface/buspirate.cfg index b02d29d06..265e37e06 100644 --- a/tcl/interface/buspirate.cfg +++ b/tcl/interface/buspirate.cfg @@ -23,4 +23,3 @@ buspirate_speed normal ;# or fast # this depends on the cable, you are safe with this option reset_config srst_only - diff --git a/tcl/interface/calao-usb-a9260.cfg b/tcl/interface/calao-usb-a9260.cfg index d1dc736da..01b426b89 100644 --- a/tcl/interface/calao-usb-a9260.cfg +++ b/tcl/interface/calao-usb-a9260.cfg @@ -8,4 +8,3 @@ adapter srst delay 200 jtag_ntrst_delay 200 - diff --git a/tcl/interface/chameleon.cfg b/tcl/interface/chameleon.cfg index f523ee73e..1cb1d6151 100644 --- a/tcl/interface/chameleon.cfg +++ b/tcl/interface/chameleon.cfg @@ -6,4 +6,3 @@ adapter driver parport parport_cable chameleon - diff --git a/tcl/interface/dummy.cfg b/tcl/interface/dummy.cfg index 6c2fe5f2f..154c872cf 100644 --- a/tcl/interface/dummy.cfg +++ b/tcl/interface/dummy.cfg @@ -3,4 +3,3 @@ # adapter driver dummy - diff --git a/tcl/interface/ftdi/hitex_lpc1768stick.cfg b/tcl/interface/ftdi/hitex_lpc1768stick.cfg index 3f49522da..9fe80f126 100644 --- a/tcl/interface/ftdi/hitex_lpc1768stick.cfg +++ b/tcl/interface/ftdi/hitex_lpc1768stick.cfg @@ -12,4 +12,3 @@ ftdi_vid_pid 0x0640 0x0026 ftdi_layout_init 0x0388 0x038b ftdi_layout_signal nTRST -data 0x0100 ftdi_layout_signal nSRST -data 0x0080 -noe 0x200 - diff --git a/tcl/interface/parport_dlc5.cfg b/tcl/interface/parport_dlc5.cfg index b1aa0a9a7..e9beaaf41 100644 --- a/tcl/interface/parport_dlc5.cfg +++ b/tcl/interface/parport_dlc5.cfg @@ -13,4 +13,3 @@ if { [info exists PARPORTADDR] } { adapter driver parport parport_port $_PARPORTADDR parport_cable dlc5 - diff --git a/tcl/interface/rlink.cfg b/tcl/interface/rlink.cfg index 3fe90ab42..29d3ce599 100644 --- a/tcl/interface/rlink.cfg +++ b/tcl/interface/rlink.cfg @@ -5,4 +5,3 @@ # adapter driver rlink - diff --git a/tcl/interface/stlink.cfg b/tcl/interface/stlink.cfg index e9a7b17b1..54cd63eb6 100644 --- a/tcl/interface/stlink.cfg +++ b/tcl/interface/stlink.cfg @@ -14,4 +14,3 @@ hla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374 # number reset issues. # eg. #hla_serial "\xaa\xbc\x6e\x06\x50\x75\xff\x55\x17\x42\x19\x3f" - diff --git a/tcl/interface/vsllink.cfg b/tcl/interface/vsllink.cfg index a587176ae..d40dbb429 100644 --- a/tcl/interface/vsllink.cfg +++ b/tcl/interface/vsllink.cfg @@ -5,4 +5,3 @@ # adapter driver vsllink - diff --git a/tcl/target/adsp-sc58x.cfg b/tcl/target/adsp-sc58x.cfg index 8c9ef1240..6073bb212 100644 --- a/tcl/target/adsp-sc58x.cfg +++ b/tcl/target/adsp-sc58x.cfg @@ -50,4 +50,3 @@ proc sc58x_enabledebug {} { # it is not possible to halt the target unless these bits have been set ap0.mem mww 0x31131000 0xFFFF } - diff --git a/tcl/target/amdm37x.cfg b/tcl/target/amdm37x.cfg index 7098adfa3..3db24b458 100644 --- a/tcl/target/amdm37x.cfg +++ b/tcl/target/amdm37x.cfg @@ -209,4 +209,3 @@ proc amdm37x_dbginit {target} { # at this address and this bit. $target mww phys 0x5401d030 0x00002000 } - diff --git a/tcl/target/ar71xx.cfg b/tcl/target/ar71xx.cfg index 0c64a96e0..57833f418 100644 --- a/tcl/target/ar71xx.cfg +++ b/tcl/target/ar71xx.cfg @@ -54,4 +54,3 @@ $_TARGETNAME configure -work-area-phys 0xa0600000 -work-area-size 0x20000 # serial SPI capable flash # flash bank - diff --git a/tcl/target/armada370.cfg b/tcl/target/armada370.cfg index 5b84637a2..3b4be9f08 100644 --- a/tcl/target/armada370.cfg +++ b/tcl/target/armada370.cfg @@ -31,4 +31,3 @@ $_TARGETNAME configure -event reset-assert-post "armada370_dbginit $_TARGETNAME" # We need to init now, so we can run the apsel command. init dap apsel 1 - diff --git a/tcl/target/at91sam3ax_8x.cfg b/tcl/target/at91sam3ax_8x.cfg index e2493837d..2bb66fbc4 100644 --- a/tcl/target/at91sam3ax_8x.cfg +++ b/tcl/target/at91sam3ax_8x.cfg @@ -7,5 +7,3 @@ flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME # This is a 512K chip - it has the 2nd bank set _FLASHNAME $_CHIPNAME.flash1 flash bank $_FLASHNAME at91sam3 0x0000C0000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3ax_xx.cfg b/tcl/target/at91sam3ax_xx.cfg index e56177122..5e01d665d 100644 --- a/tcl/target/at91sam3ax_xx.cfg +++ b/tcl/target/at91sam3ax_xx.cfg @@ -8,4 +8,3 @@ # at91sam3X8E # at91sam3X8H source [find target/at91sam3XXX.cfg] - diff --git a/tcl/target/at91sam3u1c.cfg b/tcl/target/at91sam3u1c.cfg index 47c227b26..dc5c82c07 100644 --- a/tcl/target/at91sam3u1c.cfg +++ b/tcl/target/at91sam3u1c.cfg @@ -4,5 +4,3 @@ source [find target/at91sam3uxx.cfg] # size is automatically "calculated" by probing set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u1e.cfg b/tcl/target/at91sam3u1e.cfg index 47c227b26..dc5c82c07 100644 --- a/tcl/target/at91sam3u1e.cfg +++ b/tcl/target/at91sam3u1e.cfg @@ -4,5 +4,3 @@ source [find target/at91sam3uxx.cfg] # size is automatically "calculated" by probing set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u2c.cfg b/tcl/target/at91sam3u2c.cfg index 47c227b26..dc5c82c07 100644 --- a/tcl/target/at91sam3u2c.cfg +++ b/tcl/target/at91sam3u2c.cfg @@ -4,5 +4,3 @@ source [find target/at91sam3uxx.cfg] # size is automatically "calculated" by probing set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u2e.cfg b/tcl/target/at91sam3u2e.cfg index 47c227b26..dc5c82c07 100644 --- a/tcl/target/at91sam3u2e.cfg +++ b/tcl/target/at91sam3u2e.cfg @@ -4,5 +4,3 @@ source [find target/at91sam3uxx.cfg] # size is automatically "calculated" by probing set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u4c.cfg b/tcl/target/at91sam3u4c.cfg index 5cacbcbef..14af008b6 100644 --- a/tcl/target/at91sam3u4c.cfg +++ b/tcl/target/at91sam3u4c.cfg @@ -7,5 +7,3 @@ flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME # This is a 256K chip, it has the 2nd bank set _FLASHNAME $_CHIPNAME.flash1 flash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3u4e.cfg b/tcl/target/at91sam3u4e.cfg index a48f99265..fbe2dd94b 100644 --- a/tcl/target/at91sam3u4e.cfg +++ b/tcl/target/at91sam3u4e.cfg @@ -7,5 +7,3 @@ flash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME # This is a 256K chip - it has the 2nd bank set _FLASHNAME $_CHIPNAME.flash1 flash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME - - diff --git a/tcl/target/at91sam3uxx.cfg b/tcl/target/at91sam3uxx.cfg index b42ae19cf..5b1748ba4 100644 --- a/tcl/target/at91sam3uxx.cfg +++ b/tcl/target/at91sam3uxx.cfg @@ -8,4 +8,3 @@ # at91sam3u1c source [find target/at91sam3XXX.cfg] - diff --git a/tcl/target/at91sam7se512.cfg b/tcl/target/at91sam7se512.cfg index ab0970128..61b47816b 100644 --- a/tcl/target/at91sam7se512.cfg +++ b/tcl/target/at91sam7se512.cfg @@ -36,4 +36,3 @@ $_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-a #flash bank [ ] set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432 - diff --git a/tcl/target/atsamv.cfg b/tcl/target/atsamv.cfg index 4c136ead2..fdd835473 100644 --- a/tcl/target/atsamv.cfg +++ b/tcl/target/atsamv.cfg @@ -57,4 +57,3 @@ if {![using_hla]} { set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME - diff --git a/tcl/target/avr32.cfg b/tcl/target/avr32.cfg index 7808127ca..8295f5e68 100644 --- a/tcl/target/avr32.cfg +++ b/tcl/target/avr32.cfg @@ -14,4 +14,3 @@ jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_CP set _TARGETNAME [format "%s.cpu" $_CHIPNAME] target create $_TARGETNAME avr32_ap7k -endian $_ENDIAN -chain-position $_TARGETNAME - diff --git a/tcl/target/cs351x.cfg b/tcl/target/cs351x.cfg index cb05da2cf..8fabda67f 100644 --- a/tcl/target/cs351x.cfg +++ b/tcl/target/cs351x.cfg @@ -28,4 +28,3 @@ target create $_TARGETNAME fa526 -endian $_ENDIAN -chain-position $_TARGETNAME # This chip has a DCC ... use it arm7_9 dcc_downloads enable - diff --git a/tcl/target/dragonite.cfg b/tcl/target/dragonite.cfg index 1277cca9c..b9d73a285 100644 --- a/tcl/target/dragonite.cfg +++ b/tcl/target/dragonite.cfg @@ -28,4 +28,3 @@ target create $_TARGETNAME dragonite -endian $_ENDIAN -chain-position $_TARGETNA reset_config trst_and_srst adapter srst delay 200 jtag_ntrst_delay 200 - diff --git a/tcl/target/dsp568013.cfg b/tcl/target/dsp568013.cfg index 98110c298..c0c1df2bc 100644 --- a/tcl/target/dsp568013.cfg +++ b/tcl/target/dsp568013.cfg @@ -73,4 +73,3 @@ $_TARGETNAME configure -work-area-virt 0 #setup flash set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME - diff --git a/tcl/target/dsp568037.cfg b/tcl/target/dsp568037.cfg index 010d06f9d..fc57bd435 100644 --- a/tcl/target/dsp568037.cfg +++ b/tcl/target/dsp568037.cfg @@ -69,4 +69,3 @@ $_TARGETNAME configure -work-area-virt 0 #setup flash set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME - diff --git a/tcl/target/feroceon.cfg b/tcl/target/feroceon.cfg index b9344268d..d4f710e00 100644 --- a/tcl/target/feroceon.cfg +++ b/tcl/target/feroceon.cfg @@ -28,4 +28,3 @@ target create $_TARGETNAME feroceon -endian $_ENDIAN -chain-position $_TARGETNAM reset_config trst_and_srst adapter srst delay 200 jtag_ntrst_delay 200 - diff --git a/tcl/target/hilscher_netx10.cfg b/tcl/target/hilscher_netx10.cfg index 3f96607c6..668de8fee 100644 --- a/tcl/target/hilscher_netx10.cfg +++ b/tcl/target/hilscher_netx10.cfg @@ -28,4 +28,3 @@ jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CP # that TAP is associated with a target set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME - diff --git a/tcl/target/icepick.cfg b/tcl/target/icepick.cfg index a945bea8a..36b0b7033 100644 --- a/tcl/target/icepick.cfg +++ b/tcl/target/icepick.cfg @@ -140,4 +140,3 @@ proc icepick_c_wreset {jrc} { # send a router write, block is 0, register is 1, value is 0x2100 icepick_c_router $jrc 1 0x0 0x1 0x002101 } - diff --git a/tcl/target/ixp42x.cfg b/tcl/target/ixp42x.cfg index d7b5bf470..3f86e357b 100644 --- a/tcl/target/ixp42x.cfg +++ b/tcl/target/ixp42x.cfg @@ -104,4 +104,3 @@ proc ixp42x_init_sdram { SDRAM_CFG REFRESH CASLAT } { proc ixp42x_set_bigendian { } { reg XSCALE_CTRL 0xF8 } - diff --git a/tcl/target/kx.cfg b/tcl/target/kx.cfg index 1dd5d316c..9fda4edf4 100644 --- a/tcl/target/kx.cfg +++ b/tcl/target/kx.cfg @@ -79,4 +79,3 @@ if {[using_hla]} { $_TARGETNAME configure -event reset-init { kinetis disable_wdog } - diff --git a/tcl/target/readme.txt b/tcl/target/readme.txt index 2c3cc8df1..91bb2d5f3 100644 --- a/tcl/target/readme.txt +++ b/tcl/target/readme.txt @@ -38,4 +38,3 @@ Note that a target/xxx.cfg file can invoke another target/yyy.cfg file, so one can create target subtype configurations where e.g. only amount of DRAM, oscillator speeds differ and having a single config file for the default/common settings. - diff --git a/tcl/target/samsung_s3c2440.cfg b/tcl/target/samsung_s3c2440.cfg index 2a0a915d6..a97659be5 100644 --- a/tcl/target/samsung_s3c2440.cfg +++ b/tcl/target/samsung_s3c2440.cfg @@ -32,4 +32,3 @@ $_TARGETNAME configure -work-area-phys 0x200000 -work-area-size 0x4000 -work-are #reset configuration reset_config trst_and_srst - diff --git a/tcl/target/samsung_s3c4510.cfg b/tcl/target/samsung_s3c4510.cfg index 461d0478a..8bc5da530 100644 --- a/tcl/target/samsung_s3c4510.cfg +++ b/tcl/target/samsung_s3c4510.cfg @@ -21,4 +21,3 @@ jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CP set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - diff --git a/tcl/target/sharp_lh79532.cfg b/tcl/target/sharp_lh79532.cfg index 6f2cf2234..a464839dc 100644 --- a/tcl/target/sharp_lh79532.cfg +++ b/tcl/target/sharp_lh79532.cfg @@ -22,5 +22,3 @@ jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CP set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME - - diff --git a/tcl/target/snps_em_sk_fpga.cfg b/tcl/target/snps_em_sk_fpga.cfg index d52c7e8db..2f7fecbe3 100644 --- a/tcl/target/snps_em_sk_fpga.cfg +++ b/tcl/target/snps_em_sk_fpga.cfg @@ -31,4 +31,3 @@ $_TARGETNAME configure -event reset-assert "arc_em_reset $_TARGETNAME" arc_em_init_regs # vim:ft=tcl - diff --git a/tcl/target/stm32f7x.cfg b/tcl/target/stm32f7x.cfg index db1794c19..6ad4b65f8 100644 --- a/tcl/target/stm32f7x.cfg +++ b/tcl/target/stm32f7x.cfg @@ -170,4 +170,3 @@ $_TARGETNAME configure -event reset-start { # Reduce speed since CPU speed will slow down to 16MHz with the reset adapter speed 2000 } - diff --git a/tcl/target/str730.cfg b/tcl/target/str730.cfg index 9a2719472..e9e2f26e8 100644 --- a/tcl/target/str730.cfg +++ b/tcl/target/str730.cfg @@ -51,4 +51,3 @@ $_TARGETNAME configure -work-area-phys 0xA0000000 -work-area-size 0x4000 -work-a #flash bank set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME str7x 0x80000000 0x00040000 0 0 $_TARGETNAME STR73x - diff --git a/tcl/target/u8500.cfg b/tcl/target/u8500.cfg index faaf97d17..baef9c81f 100644 --- a/tcl/target/u8500.cfg +++ b/tcl/target/u8500.cfg @@ -322,5 +322,3 @@ set mem inaccessible-by-default-off jtag_ntrst_delay 100 reset_config trst_and_srst combined - - diff --git a/tcl/test/syntax1.cfg b/tcl/test/syntax1.cfg index 04e615ec0..2e6618895 100644 --- a/tcl/test/syntax1.cfg +++ b/tcl/test/syntax1.cfg @@ -27,4 +27,3 @@ mvb 0xE01FC040 0x01 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 14765 - From 6572dd97b3a6e9c6afea81d47a507683ecc95698 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 12 May 2019 12:55:18 +0200 Subject: [PATCH 271/354] coding style: src: remove empty lines at end of text files Empty lines at end of text files are useless. Remove them. Change-Id: Ibac9b36682d58f81e34ca2b51e6260e7d472fb0e Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5172 Tested-by: jenkins --- src/helper/startup.tcl | 1 - src/jtag/aice/aice_transport.c | 1 - src/jtag/drivers/Makefile.am | 1 - src/jtag/drivers/rlink_call.m4 | 2 -- src/jtag/drivers/rlink_speed_table.c | 1 - src/jtag/drivers/sysfsgpio.c | 1 - src/rtos/embKernel.c | 1 - src/rtos/nuttx.c | 1 - src/rtos/rtos_embkernel_stackings.c | 2 -- src/rtos/rtos_mqx_stackings.c | 1 - src/target/arc_jtag.c | 1 - src/target/arm_cti.c | 1 - src/target/avr32_jtag.c | 1 - src/target/nds32_cmd.c | 1 - 14 files changed, 16 deletions(-) diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl index 691e3824f..71f489dd5 100644 --- a/src/helper/startup.tcl +++ b/src/helper/startup.tcl @@ -29,4 +29,3 @@ add_help_text script "filename of OpenOCD script (tcl) to run" add_usage_text script "" ######### - diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c index 682c6698a..d0f7a49c0 100644 --- a/src/jtag/aice/aice_transport.c +++ b/src/jtag/aice/aice_transport.c @@ -443,4 +443,3 @@ static void aice_constructor(void) { transport_register(&aice_jtag_transport); } - diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index ba758e720..07824f678 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -184,4 +184,3 @@ DRIVERHEADERS = \ %D%/versaloon/versaloon.h \ %D%/versaloon/versaloon_include.h \ %D%/versaloon/versaloon_internal.h - diff --git a/src/jtag/drivers/rlink_call.m4 b/src/jtag/drivers/rlink_call.m4 index b27f39238..bf07afa4e 100644 --- a/src/jtag/drivers/rlink_call.m4 +++ b/src/jtag/drivers/rlink_call.m4 @@ -479,5 +479,3 @@ m4_delay(HOLD_DELAY_CYCLES - 10) A = X DR_MPEG = A ; return TCK low, as str912 reset halt seems to require it BRANCH - - diff --git a/src/jtag/drivers/rlink_speed_table.c b/src/jtag/drivers/rlink_speed_table.c index b84357731..660aac414 100644 --- a/src/jtag/drivers/rlink_speed_table.c +++ b/src/jtag/drivers/rlink_speed_table.c @@ -98,4 +98,3 @@ const struct rlink_speed_table rlink_speed_table[] = {{ } }; const size_t rlink_speed_table_size = ARRAY_SIZE(rlink_speed_table); - diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index c398d5384..e4a15237b 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -715,4 +715,3 @@ static int sysfsgpio_quit(void) cleanup_all_fds(); return ERROR_OK; } - diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c index 42d2a8cd0..2f04963b4 100644 --- a/src/rtos/embKernel.c +++ b/src/rtos/embKernel.c @@ -340,4 +340,3 @@ static int embKernel_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[ return 0; } - diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c index 8c3076e16..322c7d19b 100644 --- a/src/rtos/nuttx.c +++ b/src/rtos/nuttx.c @@ -401,4 +401,3 @@ struct rtos_type nuttx_rtos = { .get_thread_reg_list = nuttx_get_thread_reg_list, .get_symbol_list_to_lookup = nuttx_get_symbol_list_to_lookup, }; - diff --git a/src/rtos/rtos_embkernel_stackings.c b/src/rtos/rtos_embkernel_stackings.c index 4ee79af93..543a8cd2a 100644 --- a/src/rtos/rtos_embkernel_stackings.c +++ b/src/rtos/rtos_embkernel_stackings.c @@ -51,5 +51,3 @@ const struct rtos_register_stacking rtos_embkernel_Cortex_M_stacking = { rtos_generic_stack_align8, /* stack_alignment */ rtos_embkernel_Cortex_M_stack_offsets /* register_offsets */ }; - - diff --git a/src/rtos/rtos_mqx_stackings.c b/src/rtos/rtos_mqx_stackings.c index 1a8bdfcc7..d18e59155 100644 --- a/src/rtos/rtos_mqx_stackings.c +++ b/src/rtos/rtos_mqx_stackings.c @@ -77,4 +77,3 @@ const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking = { NULL, /* stack_alignment */ rtos_mqx_arm_v7m_stack_offsets /* register_offsets */ }; - diff --git a/src/target/arc_jtag.c b/src/target/arc_jtag.c index 274d61f3a..e85167a6f 100644 --- a/src/target/arc_jtag.c +++ b/src/target/arc_jtag.c @@ -539,4 +539,3 @@ exit: return retval; } - diff --git a/src/target/arm_cti.c b/src/target/arm_cti.c index 1662c7e16..579bacb77 100644 --- a/src/target/arm_cti.c +++ b/src/target/arm_cti.c @@ -641,4 +641,3 @@ int cti_register_commands(struct command_context *cmd_ctx) { return register_commands(cmd_ctx, NULL, cti_command_handlers); } - diff --git a/src/target/avr32_jtag.c b/src/target/avr32_jtag.c index 6a4d4b3e7..64ebf12ba 100644 --- a/src/target/avr32_jtag.c +++ b/src/target/avr32_jtag.c @@ -369,4 +369,3 @@ int avr32_ocd_clearbits(struct avr32_jtag *jtag, int reg, uint32_t bits) return ERROR_OK; } - diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c index 1accf6f83..88d8b4512 100644 --- a/src/target/nds32_cmd.c +++ b/src/target/nds32_cmd.c @@ -1123,4 +1123,3 @@ const struct command_registration nds32_command_handlers[] = { }, COMMAND_REGISTRATION_DONE }; - From 837de9fd10e93dc369c02dd1d28c526fd1ba1ed4 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 12 May 2019 12:57:49 +0200 Subject: [PATCH 272/354] coding style: contrib: remove empty lines at end of text files Empty lines at end of text files are useless. Remove them. Change-Id: I4efbd9af5be7e16213dcc7cb95de936ecde2fcef Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5173 Tested-by: jenkins --- contrib/libdcc/README | 1 - contrib/loaders/debug/xscale/debug_handler.S | 1 - contrib/loaders/flash/armv7m_io.s | 1 - contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld | 1 - contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds | 1 - contrib/loaders/flash/stm32/stm32h7x.S | 1 - contrib/loaders/flash/stm32/stm32l4x.S | 1 - contrib/loaders/watchdog/armv7m_kinetis_wdog.s | 1 - contrib/loaders/watchdog/armv7m_kinetis_wdog32.s | 1 - contrib/xsvf_tools/svf2xsvf.py | 1 - contrib/xsvf_tools/xsvfdump.py | 1 - 11 files changed, 11 deletions(-) diff --git a/contrib/libdcc/README b/contrib/libdcc/README index d67ccce3f..1135b247e 100644 --- a/contrib/libdcc/README +++ b/contrib/libdcc/README @@ -16,4 +16,3 @@ To see how many times the trace point was hit: Spen spen@spen-soft.co.uk - diff --git a/contrib/loaders/debug/xscale/debug_handler.S b/contrib/loaders/debug/xscale/debug_handler.S index 66dfa8891..0f62d9c14 100644 --- a/contrib/loaders/debug/xscale/debug_handler.S +++ b/contrib/loaders/debug/xscale/debug_handler.S @@ -713,4 +713,3 @@ send_to_debugger: receive_from_debugger: m_receive_from_debugger r0 mov pc, lr - diff --git a/contrib/loaders/flash/armv7m_io.s b/contrib/loaders/flash/armv7m_io.s index 797981c53..f6dbbe9bf 100644 --- a/contrib/loaders/flash/armv7m_io.s +++ b/contrib/loaders/flash/armv7m_io.s @@ -57,4 +57,3 @@ done_write: bkpt #0 .end - diff --git a/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld b/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld index ea06931d0..8cb21184f 100644 --- a/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld +++ b/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld @@ -129,4 +129,3 @@ SECTIONS } /*** EOF ***/ - diff --git a/contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds b/contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds index 7798b304a..0e7aa2dee 100644 --- a/contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds +++ b/contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds @@ -148,4 +148,3 @@ SECTIONS { __stack_top = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK); PROVIDE(__stack = __stack_top); } - diff --git a/contrib/loaders/flash/stm32/stm32h7x.S b/contrib/loaders/flash/stm32/stm32h7x.S index a4317229e..99e416753 100644 --- a/contrib/loaders/flash/stm32/stm32h7x.S +++ b/contrib/loaders/flash/stm32/stm32h7x.S @@ -113,4 +113,3 @@ exit: bkpt #0x00 .pool - diff --git a/contrib/loaders/flash/stm32/stm32l4x.S b/contrib/loaders/flash/stm32/stm32l4x.S index 9e5c41eba..9923ce772 100644 --- a/contrib/loaders/flash/stm32/stm32l4x.S +++ b/contrib/loaders/flash/stm32/stm32l4x.S @@ -103,4 +103,3 @@ exit: movs r6, #FLASH_ERROR /* all error bits */ str r6, [r4] /* write to FLASH_CR to clear errors */ bkpt #0x00 - diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s index d7241927c..2a7eb8984 100644 --- a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s +++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s @@ -61,4 +61,3 @@ done: bkpt #0 .end - diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s index bf58327e9..1284ab0a2 100644 --- a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s +++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s @@ -78,4 +78,3 @@ done: bkpt #0 .end - diff --git a/contrib/xsvf_tools/svf2xsvf.py b/contrib/xsvf_tools/svf2xsvf.py index 113e0a61a..6da7ff4a8 100644 --- a/contrib/xsvf_tools/svf2xsvf.py +++ b/contrib/xsvf_tools/svf2xsvf.py @@ -726,4 +726,3 @@ finally: cmdbuf[0] = XCOMPLETE output.write( cmdbuf ) output.close() - diff --git a/contrib/xsvf_tools/xsvfdump.py b/contrib/xsvf_tools/xsvfdump.py index e65f8d5b2..0e00ca05c 100644 --- a/contrib/xsvf_tools/xsvfdump.py +++ b/contrib/xsvf_tools/xsvfdump.py @@ -265,4 +265,3 @@ def main(): if __name__ == "__main__": main() - From ebc28710051402e38a4743dfde20f1d1c2f7a875 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 20 Apr 2020 23:54:38 +0200 Subject: [PATCH 273/354] server: set tcp port and bind address before init All the servers open the listening socket during openocd "init"; it's not possible to change the tcp port or the bind address after "init". In current code, the call order during "init" permits to change the port and bind address of tcl and telnet server if the related command is issued after "init" in the same script or on openocd command line. This is not guaranteed to work if the call order during "init" changes, so it's incorrect. Change the commands "bindto" and "*_port" to COMMAND_CONFIG. Change-Id: Id88f225a67a872b4bcaf3b799466bddedc248015 Signed-off-by: Antonio Borneo Reported-by: Christopher Head Fixes: https://sourceforge.net/p/openocd/tickets/264/ Reviewed-on: http://openocd.zylin.com/5595 Reviewed-by: Christopher Head Tested-by: jenkins --- src/server/gdb_server.c | 2 +- src/server/server.c | 2 +- src/server/tcl_server.c | 2 +- src/server/telnet_server.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 6f326fe24..f9fe4c293 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -3739,7 +3739,7 @@ static const struct command_registration gdb_command_handlers[] = { { .name = "gdb_port", .handler = handle_gdb_port_command, - .mode = COMMAND_ANY, + .mode = COMMAND_CONFIG, .help = "Normally gdb listens to a TCP/IP port. Each subsequent GDB " "server listens for the next port number after the " "base port number specified. " diff --git a/src/server/server.c b/src/server/server.c index f32a9c76f..07b7ae487 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -799,7 +799,7 @@ static const struct command_registration server_command_handlers[] = { { .name = "bindto", .handler = &handle_bindto_command, - .mode = COMMAND_ANY, + .mode = COMMAND_CONFIG, .usage = "[name]", .help = "Specify address by name on which to listen for " "incoming TCP/IP connections", diff --git a/src/server/tcl_server.c b/src/server/tcl_server.c index 1735c43ff..1ecb827a1 100644 --- a/src/server/tcl_server.c +++ b/src/server/tcl_server.c @@ -331,7 +331,7 @@ static const struct command_registration tcl_command_handlers[] = { { .name = "tcl_port", .handler = handle_tcl_port_command, - .mode = COMMAND_ANY, + .mode = COMMAND_CONFIG, .help = "Specify port on which to listen " "for incoming Tcl syntax. " "Read help on 'gdb_port'.", diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c index a864f5fd2..bfabae833 100644 --- a/src/server/telnet_server.c +++ b/src/server/telnet_server.c @@ -705,7 +705,7 @@ static const struct command_registration telnet_command_handlers[] = { { .name = "telnet_port", .handler = handle_telnet_port_command, - .mode = COMMAND_ANY, + .mode = COMMAND_CONFIG, .help = "Specify port on which to listen " "for incoming telnet connections. " "Read help on 'gdb_port'.", From 8f2afaafe2e905f3e59f96ee3bf0fcb353db061d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 22 Apr 2020 22:39:07 +0200 Subject: [PATCH 274/354] jtag: remove unused function adapter_driver_modules_load() Commit c2cecc74b0ac ("Move JTAG interface list to new files.") merged in mid 2009 introduces an unused and empty function that the developer expects to use for loading adapter drivers from shared libraries. This have never happened and the function is still empty and unused. Remove it. Change-Id: I7c88dbf8a9747e96e5ca4e6e7038ac0f232604fd Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5601 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/jtag/interfaces.c | 5 ----- src/jtag/interfaces.h | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c index 25858ea73..7d3f8a8ca 100644 --- a/src/jtag/interfaces.c +++ b/src/jtag/interfaces.c @@ -261,8 +261,3 @@ struct adapter_driver *adapter_drivers[] = { #endif /* standard drivers */ NULL, }; - -void adapter_driver_modules_load(const char *path) -{ - /* @todo: implement dynamic module loading for adapter drivers */ -} diff --git a/src/jtag/interfaces.h b/src/jtag/interfaces.h index f85865a24..ddbd73506 100644 --- a/src/jtag/interfaces.h +++ b/src/jtag/interfaces.h @@ -36,9 +36,6 @@ #include -/** Dynamically load all adapter driver modules from specified directory. */ -void adapter_driver_modules_load(const char *path); - extern struct adapter_driver *adapter_drivers[]; #endif /* OPENOCD_JTAG_INTERFACES_H */ From e888fe39878d87a9a36b0e7b7e8daa54bf39e23e Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sun, 20 Oct 2019 10:08:07 +0200 Subject: [PATCH 275/354] target/armv7m: cosmetic refactorization Introduce a variable 'size' and reduce the number of dereferencing *reg_list_size by using the variable. Change-Id: I3bdf1485a4ed8e34435e8acb3efd0df8d802508c Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5326 Tested-by: jenkins Reviewed-by: Christopher Head Reviewed-by: Antonio Borneo --- src/target/armv7m.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/target/armv7m.c b/src/target/armv7m.c index 837ccc94e..017d693ce 100644 --- a/src/target/armv7m.c +++ b/src/target/armv7m.c @@ -301,20 +301,22 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size, enum target_register_class reg_class) { struct armv7m_common *armv7m = target_to_armv7m(target); - int i; + int i, size; if (reg_class == REG_CLASS_ALL) - *reg_list_size = armv7m->arm.core_cache->num_regs; + size = armv7m->arm.core_cache->num_regs; else - *reg_list_size = ARMV7M_NUM_CORE_REGS; + size = ARMV7M_NUM_CORE_REGS; - *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); + *reg_list = malloc(sizeof(struct reg *) * size); if (*reg_list == NULL) return ERROR_FAIL; - for (i = 0; i < *reg_list_size; i++) + for (i = 0; i < size; i++) (*reg_list)[i] = &armv7m->arm.core_cache->reg_list[i]; + *reg_list_size = size; + return ERROR_OK; } From f6cf18556420cd2d7fb747866392b118ec71c036 Mon Sep 17 00:00:00 2001 From: Andreas Bolsch Date: Sun, 15 Mar 2020 12:21:37 +0100 Subject: [PATCH 276/354] revision id for STM32L4P5/Q5 corrected According to RM0432 rev. 6, only 0x1001 "Z" rev. applies for STM32L4P5/Q5. Verified on real device. Whether other revisions exist is unclear. Change-Id: I761ae077d089b06925fc0fe1ff2b1e478b8a66fa Signed-off-by: Andreas Bolsch Reviewed-on: http://openocd.zylin.com/5521 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Tomas Vanek --- src/flash/nor/stm32l4x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 4b7edae5f..74fba35c1 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -181,7 +181,7 @@ static const struct stm32l4_rev stm32_470_revs[] = { }; static const struct stm32l4_rev stm32_471_revs[] = { - { 0x1000, "1" }, + { 0x1001, "Z" }, }; static const struct stm32l4_rev stm32_495_revs[] = { From 880508f68fc58aa00ce5b7005e06221dba89c69e Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 9 Mar 2020 19:10:56 +0100 Subject: [PATCH 277/354] flash/stm32l4x: always use stm32l4_get_flash_reg this change is a preparation for STM32L5 support on top of L4 driver STM32L5 flash is quite similar to L4 flash, mainly register names and offsets and some bits are changed. a table with register offset will be introduced, thus correct register addresses will be obtained using this table and the driver internal function 'stm32l4_get_flash_reg' will be responsible of this. Change-Id: I74bf61a83fe53575623640af0328b3253ecc796f Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5508 Tested-by: jenkins Reviewed-by: Andreas Bolsch Reviewed-by: Michael Jung Reviewed-by: Tomas Vanek --- src/flash/nor/stm32l4x.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 74fba35c1..38f8b3b99 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -671,7 +671,6 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct target *target = bank->target; - struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; uint32_t buffer_size; struct working_area *write_algorithm; struct working_area *source; @@ -727,8 +726,8 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size); buf_set_u32(reg_params[2].value, 0, 32, address); buf_set_u32(reg_params[3].value, 0, 32, count); - buf_set_u32(reg_params[4].value, 0, 32, stm32l4_info->part_info->flash_regs_base + STM32_FLASH_SR); - buf_set_u32(reg_params[5].value, 0, 32, stm32l4_info->part_info->flash_regs_base + STM32_FLASH_CR); + buf_set_u32(reg_params[4].value, 0, 32, stm32l4_get_flash_reg(bank, STM32_FLASH_SR)); + buf_set_u32(reg_params[5].value, 0, 32, stm32l4_get_flash_reg(bank, STM32_FLASH_CR)); retval = target_run_flash_async_algorithm(target, buffer, count, 8, 0, NULL, @@ -1144,7 +1143,7 @@ static int stm32l4_mass_erase(struct flash_bank *bank) if (retval != ERROR_OK) goto err_lock; - retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); + retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); err_lock: retval2 = stm32l4_write_flash_reg(bank, STM32_FLASH_CR, FLASH_LOCK); From 968d3851e742ffa74b7f817d54f23db1d85929ef Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Mon, 13 Apr 2020 17:33:10 +0200 Subject: [PATCH 278/354] loaders/flash/nrf5: add CPU type to loader source Change-Id: Ia65ac21bd99d76c8dace4e9ede060e870cad14de Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5588 Tested-by: jenkins Reviewed-by: Antonio Borneo --- contrib/loaders/flash/nrf5/nrf5.S | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/loaders/flash/nrf5/nrf5.S b/contrib/loaders/flash/nrf5/nrf5.S index 53551a2c2..12b1d92b5 100644 --- a/contrib/loaders/flash/nrf5/nrf5.S +++ b/contrib/loaders/flash/nrf5/nrf5.S @@ -19,6 +19,7 @@ .text .syntax unified + .cpu cortex-m0 .thumb /* From 05eb9a357cd2794a83f8176827cb3a59db375683 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 17 Oct 2019 15:12:55 -0700 Subject: [PATCH 279/354] Add get_thread_reg() and set_reg() for hwthread get_thread_reg() allows gdb to request the register value of a specific "thread." set_reg() allows register writes without getting a giant list of registers first. Signed-off-by: Tim Newsome Change-Id: I87faa1c8793916b9ee476dd696f0695a07ca2b41 Reviewed-on: http://openocd.zylin.com/5324 Tested-by: jenkins --- src/rtos/hwthread.c | 141 ++++++++++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 51 deletions(-) diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c index 2d9e42fa6..38e42a041 100644 --- a/src/rtos/hwthread.c +++ b/src/rtos/hwthread.c @@ -31,10 +31,13 @@ static bool hwthread_detect_rtos(struct target *target); static int hwthread_create(struct target *target); static int hwthread_update_threads(struct rtos *rtos); +static int hwthread_get_thread_reg(struct rtos *rtos, int64_t thread_id, + uint32_t reg_num, struct rtos_reg *rtos_reg); static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, - struct rtos_reg **reg_list, int *num_regs); + struct rtos_reg **reg_list, int *num_regs); static int hwthread_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); static int hwthread_smp_init(struct target *target); +int hwthread_set_reg(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value); #define HW_THREAD_NAME_STR_SIZE (32) @@ -51,8 +54,10 @@ const struct rtos_type hwthread_rtos = { .create = hwthread_create, .update_threads = hwthread_update_threads, .get_thread_reg_list = hwthread_get_thread_reg_list, + .get_thread_reg = hwthread_get_thread_reg, .get_symbol_list_to_lookup = hwthread_get_symbol_list_to_lookup, .smp_init = hwthread_smp_init, + .set_reg = hwthread_set_reg, }; struct hwthread_params { @@ -201,64 +206,114 @@ static int hwthread_smp_init(struct target *target) return hwthread_update_threads(target->rtos); } -static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, - struct rtos_reg **rtos_reg_list, int *num_regs) +static struct target *hwthread_find_thread(struct target *target, int64_t thread_id) { - struct target_list *head; - struct target *target; - struct target *curr; - struct reg **reg_list; - int retval; + /* Find the thread with that thread_id */ + if (target == NULL) + return NULL; + if (target->smp) { + for (struct target_list *head = target->head; head != NULL; head = head->next) { + if (thread_id == threadid_from_target(head->target)) + return head->target; + } + } else if (thread_id == threadid_from_target(target)) { + return target; + } + return NULL; +} +static int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, + struct rtos_reg **rtos_reg_list, int *rtos_reg_list_size) +{ if (rtos == NULL) return ERROR_FAIL; - target = rtos->target; + struct target *target = rtos->target; - /* Find the thread with that thread_id */ - if (target->smp) { - curr = NULL; - for (head = target->head; head != NULL; head = head->next) { - curr = head->target; - - if (thread_id == threadid_from_target(curr)) - break; - } - - if (head == NULL) - return ERROR_FAIL; - } else { - curr = target; - if (thread_id != threadid_from_target(curr)) - return ERROR_FAIL; - - } + struct target *curr = hwthread_find_thread(target, thread_id); + if (curr == NULL) + return ERROR_FAIL; if (!target_was_examined(curr)) return ERROR_FAIL; - retval = target_get_gdb_reg_list(curr, ®_list, num_regs, + struct reg **reg_list; + int retval = target_get_gdb_reg_list(curr, ®_list, rtos_reg_list_size, REG_CLASS_GENERAL); if (retval != ERROR_OK) return retval; - *rtos_reg_list = calloc(*num_regs, sizeof(struct rtos_reg)); + *rtos_reg_list = calloc(*rtos_reg_list_size, sizeof(struct rtos_reg)); if (*rtos_reg_list == NULL) { free(reg_list); return ERROR_FAIL; } - for (int i = 0; i < *num_regs; i++) { + for (int i = 0; i < *rtos_reg_list_size; i++) { (*rtos_reg_list)[i].number = (*reg_list)[i].number; (*rtos_reg_list)[i].size = (*reg_list)[i].size; memcpy((*rtos_reg_list)[i].value, (*reg_list)[i].value, - ((*reg_list)[i].size + 7) / 8); + ((*reg_list)[i].size + 7) / 8); } - free(reg_list); return ERROR_OK; +} +static int hwthread_get_thread_reg(struct rtos *rtos, int64_t thread_id, + uint32_t reg_num, struct rtos_reg *rtos_reg) +{ + if (rtos == NULL) + return ERROR_FAIL; + + struct target *target = rtos->target; + + struct target *curr = hwthread_find_thread(target, thread_id); + if (curr == NULL) { + LOG_ERROR("Couldn't find RTOS thread for id %" PRId64 ".", thread_id); + return ERROR_FAIL; + } + + if (!target_was_examined(curr)) { + LOG_ERROR("Target %d hasn't been examined yet.", curr->coreid); + return ERROR_FAIL; + } + + struct reg *reg = register_get_by_number(curr->reg_cache, reg_num, true); + if (!reg) { + LOG_ERROR("Couldn't find register %d in thread %" PRId64 ".", reg_num, + thread_id); + return ERROR_FAIL; + } + + if (reg->type->get(reg) != ERROR_OK) + return ERROR_FAIL; + + rtos_reg->number = reg->number; + rtos_reg->size = reg->size; + unsigned bytes = (reg->size + 7) / 8; + assert(bytes <= sizeof(rtos_reg->value)); + memcpy(rtos_reg->value, reg->value, bytes); + + return ERROR_OK; +} + +int hwthread_set_reg(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value) +{ + if (rtos == NULL) + return ERROR_FAIL; + + struct target *target = rtos->target; + + struct target *curr = hwthread_find_thread(target, rtos->current_thread); + if (curr == NULL) + return ERROR_FAIL; + + struct reg *reg = register_get_by_number(curr->reg_cache, reg_num, true); + if (!reg) + return ERROR_FAIL; + + return reg->type->set(reg, reg_value); } static int hwthread_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) @@ -272,26 +327,10 @@ static int hwthread_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[] static int hwthread_target_for_threadid(struct connection *connection, int64_t thread_id, struct target **p_target) { struct target *target = get_target_from_connection(connection); - struct target_list *head; - struct target *curr; - if (target->smp) { - /* Find the thread with that thread_id */ - curr = NULL; - for (head = target->head; head != NULL; head = head->next) { - curr = head->target; - - if (thread_id == threadid_from_target(curr)) - break; - } - - if (head == NULL) - return ERROR_FAIL; - } else { - curr = target; - if (thread_id != threadid_from_target(curr)) - return ERROR_FAIL; - } + struct target *curr = hwthread_find_thread(target, thread_id); + if (curr == NULL) + return ERROR_FAIL; *p_target = curr; From 0af37282c742dfc3492348f44f66215939148fb0 Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Wed, 18 Mar 2020 16:12:04 +0300 Subject: [PATCH 280/354] target/arc: Add initial stepping functions Change-Id: I84845f2ec6f1cff975990f0a495165a02de33227 Signed-off-by: Evgeniy Didin Reviewed-on: http://openocd.zylin.com/5643 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/arc.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++- src/target/arc.h | 7 +++- 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/target/arc.c b/src/target/arc.c index 823b9ed70..396bf8a47 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -1286,6 +1286,107 @@ static int arc_target_create(struct target *target, Jim_Interp *interp) } +/* Helper function which swiches core to single_step mode by + * doing aux r/w operations. */ +int arc_config_step(struct target *target, int enable_step) +{ + uint32_t value; + + struct arc_common *arc = target_to_arc(target); + + /* enable core debug step mode */ + if (enable_step) { + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, + &value)); + value &= ~SET_CORE_AE_BIT; /* clear the AE bit */ + CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, + value)); + LOG_DEBUG(" [status32:0x%08" PRIx32 "]", value); + + /* Doing read-modify-write, because DEBUG might contain manually set + * bits like UB or ED, which should be preserved. */ + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, + AUX_DEBUG_REG, &value)); + value |= SET_CORE_SINGLE_INSTR_STEP; /* set the IS bit */ + CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG, + value)); + LOG_DEBUG("core debug step mode enabled [debug-reg:0x%08" PRIx32 "]", value); + + } else { /* disable core debug step mode */ + CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG, + &value)); + value &= ~SET_CORE_SINGLE_INSTR_STEP; /* clear the IS bit */ + CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG, + value)); + LOG_DEBUG("core debug step mode disabled"); + } + + return ERROR_OK; +} + +int arc_step(struct target *target, int current, target_addr_t address, + int handle_breakpoints) +{ + /* get pointers to arch-specific information */ + struct arc_common *arc = target_to_arc(target); + struct breakpoint *breakpoint = NULL; + struct reg *pc = &(arc->core_and_aux_cache->reg_list[arc->pc_index_in_cache]); + + if (target->state != TARGET_HALTED) { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* current = 1: continue on current pc, otherwise continue at
*/ + if (!current) { + buf_set_u32(pc->value, 0, 32, address); + pc->dirty = 1; + pc->valid = 1; + } + + LOG_DEBUG("Target steps one instruction from PC=0x%" PRIx32, + buf_get_u32(pc->value, 0, 32)); + + /* the front-end may request us not to handle breakpoints */ + if (handle_breakpoints) { + breakpoint = breakpoint_find(target, buf_get_u32(pc->value, 0, 32)); + if (breakpoint) + CHECK_RETVAL(arc_unset_breakpoint(target, breakpoint)); + } + + /* restore context */ + CHECK_RETVAL(arc_restore_context(target)); + + target->debug_reason = DBG_REASON_SINGLESTEP; + + CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED)); + + /* disable interrupts while stepping */ + CHECK_RETVAL(arc_enable_interrupts(target, 0)); + + /* do a single step */ + CHECK_RETVAL(arc_config_step(target, 1)); + + /* make sure we done our step */ + alive_sleep(1); + + /* registers are now invalid */ + register_cache_invalidate(arc->core_and_aux_cache); + + if (breakpoint) + CHECK_RETVAL(arc_set_breakpoint(target, breakpoint)); + + LOG_DEBUG("target stepped "); + + target->state = TARGET_HALTED; + + /* Saving context */ + CHECK_RETVAL(arc_debug_entry(target)); + CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED)); + + return ERROR_OK; +} + /* ARC v2 target */ struct target_type arcv2_target = { .name = "arcv2", @@ -1300,7 +1401,7 @@ struct target_type arcv2_target = { .halt = arc_halt, .resume = arc_resume, - .step = NULL, + .step = arc_step, .assert_reset = arc_assert_reset, .deassert_reset = arc_deassert_reset, diff --git a/src/target/arc.h b/src/target/arc.h index af4149f97..c02787e33 100644 --- a/src/target/arc.h +++ b/src/target/arc.h @@ -33,9 +33,14 @@ #define AUX_PC_REG 0x6 #define AUX_STATUS32_REG 0xA + #define SET_CORE_FORCE_HALT BIT(1) #define SET_CORE_HALT_BIT BIT(0) /* STATUS32[0] = H field */ -#define SET_CORE_ENABLE_INTERRUPTS BIT(31) +#define SET_CORE_ENABLE_INTERRUPTS BIT(31) +/* STATUS32[5] or AE bit indicates if the processor is in exception state */ +#define SET_CORE_AE_BIT BIT(5) +/* Single instruction step bit in Debug register */ +#define SET_CORE_SINGLE_INSTR_STEP BIT(11) #define AUX_STATUS32_REG_HALT_BIT BIT(0) #define AUX_STATUS32_REG_IE_BIT BIT(31) /* STATUS32[31] = IE field */ From c693508f7717d3e5cf118da38d4a5411c59cef1a Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Mon, 16 Mar 2020 15:00:16 +0300 Subject: [PATCH 281/354] target/arc: introduce arc_read/write_instruction functions This commit introduces helper instruction read/write functions for further bp functionality. Change-Id: I619fbe2870ef6365c29ed1618bb83b6f7eb84690 Signed-off-by: Evgeniy Didin Reviewed-on: http://openocd.zylin.com/5640 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/arc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ src/target/arc.h | 23 ++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/src/target/arc.c b/src/target/arc.c index 396bf8a47..5bc6134d0 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -1285,6 +1285,62 @@ static int arc_target_create(struct target *target, Jim_Interp *interp) return ERROR_OK; } +/** + * Write 4-byte instruction to memory. This is like target_write_u32, however + * in case of little endian ARC instructions are in middle endian format, not + * little endian, so different type of conversion should be done. + * Middle endinan: instruction "aabbccdd", stored as "bbaaddcc" + */ +int arc_write_instruction_u32(struct target *target, uint32_t address, + uint32_t instr) +{ + uint8_t value_buf[4]; + if (!target_was_examined(target)) { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + + LOG_DEBUG("Address: 0x%08" PRIx32 ", value: 0x%08" PRIx32, address, + instr); + + if (target->endianness == TARGET_LITTLE_ENDIAN) + arc_h_u32_to_me(value_buf, instr); + else + h_u32_to_be(value_buf, instr); + + CHECK_RETVAL(target_write_buffer(target, address, 4, value_buf)); + + return ERROR_OK; +} + +/** + * Read 32-bit instruction from memory. It is like target_read_u32, however in + * case of little endian ARC instructions are in middle endian format, so + * different type of conversion should be done. + */ +int arc_read_instruction_u32(struct target *target, uint32_t address, + uint32_t *value) +{ + uint8_t value_buf[4]; + + if (!target_was_examined(target)) { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + + *value = 0; + CHECK_RETVAL(target_read_buffer(target, address, 4, value_buf)); + + if (target->endianness == TARGET_LITTLE_ENDIAN) + *value = arc_me_to_h_u32(value_buf); + else + *value = be_to_h_u32(value_buf); + + LOG_DEBUG("Address: 0x%08" PRIx32 ", value: 0x%08" PRIx32, address, + *value); + + return ERROR_OK; +} /* Helper function which swiches core to single_step mode by * doing aux r/w operations. */ diff --git a/src/target/arc.h b/src/target/arc.h index c02787e33..55a1ead21 100644 --- a/src/target/arc.h +++ b/src/target/arc.h @@ -160,6 +160,29 @@ static inline struct arc_common *target_to_arc(struct target *target) return target->arch_info; } +/* ----- Inlined functions ------------------------------------------------- */ + +/** + * Convert data in host endianness to the middle endian. This is required to + * write 4-byte instructions. + */ +static inline void arc_h_u32_to_me(uint8_t *buf, int val) +{ + buf[1] = (uint8_t) (val >> 24); + buf[0] = (uint8_t) (val >> 16); + buf[3] = (uint8_t) (val >> 8); + buf[2] = (uint8_t) (val >> 0); +} + +/** + * Convert data in middle endian to host endian. This is required to read 32-bit + * instruction from little endian ARCs. + */ +static inline uint32_t arc_me_to_h_u32(const uint8_t *buf) +{ + return (uint32_t)(buf[2] | buf[3] << 8 | buf[0] << 16 | buf[1] << 24); +} + /* ARC Register description */ struct arc_reg_desc { From da41bce3aee99f1fd2c661f874c90d20b4fefa04 Mon Sep 17 00:00:00 2001 From: Evgeniy Didin Date: Mon, 16 Mar 2020 20:38:00 +0300 Subject: [PATCH 282/354] target/arc: introduce breakpoint functionality With this patch we introduce set/unset breakpoints routines and add/remove bp handlers. Currently soft breakpoints are only supported. Changes since v1: * Change if-statement in arc_remove_breakpoint * Squash changes from http://openocd.zylin.com/#/c/5641/ in this commit to fix build. Change-Id: Ib10ccdb02fd1606e4f407f012b1bee106a8ffccd Signed-off-by: Evgeniy Didin Reviewed-on: http://openocd.zylin.com/5641 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/target/arc.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++- src/target/arc.h | 6 ++ 2 files changed, 162 insertions(+), 2 deletions(-) diff --git a/src/target/arc.c b/src/target/arc.c index 5bc6134d0..bf744962a 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -1342,6 +1342,158 @@ int arc_read_instruction_u32(struct target *target, uint32_t address, return ERROR_OK; } +static int arc_set_breakpoint(struct target *target, + struct breakpoint *breakpoint) +{ + + if (breakpoint->set) { + LOG_WARNING("breakpoint already set"); + return ERROR_OK; + } + + if (breakpoint->type == BKPT_SOFT) { + LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id); + + if (breakpoint->length == 4) { + uint32_t verify = 0xffffffff; + + CHECK_RETVAL(target_read_buffer(target, breakpoint->address, breakpoint->length, + breakpoint->orig_instr)); + + CHECK_RETVAL(arc_write_instruction_u32(target, breakpoint->address, + ARC_SDBBP_32)); + + CHECK_RETVAL(arc_read_instruction_u32(target, breakpoint->address, &verify)); + + if (verify != ARC_SDBBP_32) { + LOG_ERROR("Unable to set 32bit breakpoint at address @0x%" TARGET_PRIxADDR + " - check that memory is read/writable", breakpoint->address); + return ERROR_FAIL; + } + } else if (breakpoint->length == 2) { + uint16_t verify = 0xffff; + + CHECK_RETVAL(target_read_buffer(target, breakpoint->address, breakpoint->length, + breakpoint->orig_instr)); + CHECK_RETVAL(target_write_u16(target, breakpoint->address, ARC_SDBBP_16)); + + CHECK_RETVAL(target_read_u16(target, breakpoint->address, &verify)); + if (verify != ARC_SDBBP_16) { + LOG_ERROR("Unable to set 16bit breakpoint at address @0x%" TARGET_PRIxADDR + " - check that memory is read/writable", breakpoint->address); + return ERROR_FAIL; + } + } else { + LOG_ERROR("Invalid breakpoint length: target supports only 2 or 4"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + breakpoint->set = 64; /* Any nice value but 0 */ + } else if (breakpoint->type == BKPT_HARD) { + LOG_DEBUG("Hardware breakpoints are not supported yet!"); + return ERROR_FAIL; + } else { + LOG_DEBUG("ERROR: setting unknown breakpoint type"); + return ERROR_FAIL; + } + /* core instruction cache is now invalid, + * TODO: add cache invalidation function here (when implemented). */ + + return ERROR_OK; +} + +static int arc_unset_breakpoint(struct target *target, + struct breakpoint *breakpoint) +{ + int retval = ERROR_OK; + + if (!breakpoint->set) { + LOG_WARNING("breakpoint not set"); + return ERROR_OK; + } + + if (breakpoint->type == BKPT_SOFT) { + /* restore original instruction (kept in target endianness) */ + LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id); + if (breakpoint->length == 4) { + uint32_t current_instr; + + /* check that user program has not modified breakpoint instruction */ + CHECK_RETVAL(arc_read_instruction_u32(target, breakpoint->address, ¤t_instr)); + + if (current_instr == ARC_SDBBP_32) { + retval = target_write_buffer(target, breakpoint->address, + breakpoint->length, breakpoint->orig_instr); + if (retval != ERROR_OK) + return retval; + } else { + LOG_WARNING("Software breakpoint @0x%" TARGET_PRIxADDR + " has been overwritten outside of debugger." + "Expected: @0x%" PRIx32 ", got: @0x%" PRIx32, + breakpoint->address, ARC_SDBBP_32, current_instr); + } + } else if (breakpoint->length == 2) { + uint16_t current_instr; + + /* check that user program has not modified breakpoint instruction */ + CHECK_RETVAL(target_read_u16(target, breakpoint->address, ¤t_instr)); + if (current_instr == ARC_SDBBP_16) { + retval = target_write_buffer(target, breakpoint->address, + breakpoint->length, breakpoint->orig_instr); + if (retval != ERROR_OK) + return retval; + } else { + LOG_WARNING("Software breakpoint @0x%" TARGET_PRIxADDR + " has been overwritten outside of debugger. " + "Expected: 0x%04" PRIx16 ", got: 0x%04" PRIx16, + breakpoint->address, ARC_SDBBP_16, current_instr); + } + } else { + LOG_ERROR("Invalid breakpoint length: target supports only 2 or 4"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + breakpoint->set = 0; + + } else if (breakpoint->type == BKPT_HARD) { + LOG_WARNING("Hardware breakpoints are not supported yet!"); + return ERROR_FAIL; + } else { + LOG_DEBUG("ERROR: unsetting unknown breakpoint type"); + return ERROR_FAIL; + } + + /* core instruction cache is now invalid. + * TODO: Add cache invalidation function */ + + return retval; +} + + +static int arc_add_breakpoint(struct target *target, struct breakpoint *breakpoint) +{ + if (target->state == TARGET_HALTED) { + return arc_set_breakpoint(target, breakpoint); + + } else { + LOG_WARNING(" > core was not halted, please try again."); + return ERROR_TARGET_NOT_HALTED; + } +} + +static int arc_remove_breakpoint(struct target *target, + struct breakpoint *breakpoint) +{ + if (target->state == TARGET_HALTED) { + if (breakpoint->set) + CHECK_RETVAL(arc_unset_breakpoint(target, breakpoint)); + } else { + LOG_WARNING("target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + return ERROR_OK; +} + /* Helper function which swiches core to single_step mode by * doing aux r/w operations. */ int arc_config_step(struct target *target, int enable_step) @@ -1443,6 +1595,8 @@ int arc_step(struct target *target, int current, target_addr_t address, return ERROR_OK; } + + /* ARC v2 target */ struct target_type arcv2_target = { .name = "arcv2", @@ -1472,10 +1626,10 @@ struct target_type arcv2_target = { .checksum_memory = NULL, .blank_check_memory = NULL, - .add_breakpoint = NULL, + .add_breakpoint = arc_add_breakpoint, .add_context_breakpoint = NULL, .add_hybrid_breakpoint = NULL, - .remove_breakpoint = NULL, + .remove_breakpoint = arc_remove_breakpoint, .add_watchpoint = NULL, .remove_watchpoint = NULL, .hit_watchpoint = NULL, diff --git a/src/target/arc.h b/src/target/arc.h index 55a1ead21..defa3fa97 100644 --- a/src/target/arc.h +++ b/src/target/arc.h @@ -54,6 +54,12 @@ /* Limit reg_type/reg_type_field name to 20 symbols */ #define REG_TYPE_MAX_NAME_LENGTH 20 +/* ARC 32bits opcodes */ +#define ARC_SDBBP_32 0x256F003F /* BRK */ + +/* ARC 16bits opcodes */ +#define ARC_SDBBP_16 0x7FFF /* BRK_S */ + struct arc_reg_bitfield { struct reg_data_type_bitfield bitfield; char name[REG_TYPE_MAX_NAME_LENGTH]; From ed8d4a2e3b5ac5d5ac9ef7933a1d81b32d32ab7f Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 20 Feb 2020 21:49:17 +0100 Subject: [PATCH 283/354] flash/nor/kinetis: Minor code cleanups Change-Id: Id74cb6c238b803d1a1566fc615e22ea478f2e15e Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5459 Tested-by: jenkins Reviewed-by: Lars Poeschel Reviewed-by: Antonio Borneo --- src/flash/nor/kinetis.c | 60 ++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index 1d6335282..bceaf8474 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -787,9 +787,8 @@ COMMAND_HANDLER(kinetis_check_flash_security_status) if ((val & (MDM_STAT_SYSSEC | MDM_STAT_FREADY)) != MDM_STAT_FREADY) { uint32_t stats[32]; - int i; - for (i = 0; i < 32; i++) { + for (unsigned int i = 0; i < 32; i++) { stats[i] = MDM_STAT_FREADY; dap_queue_ap_read(dap_ap(dap, MDM_AP), MDM_REG_STAT, &stats[i]); } @@ -798,7 +797,7 @@ COMMAND_HANDLER(kinetis_check_flash_security_status) LOG_DEBUG("MDM: dap_run failed when validating secured state"); return ERROR_OK; } - for (i = 0; i < 32; i++) { + for (unsigned int i = 0; i < 32; i++) { if (stats[i] & MDM_STAT_SYSSEC) secured_score++; if (!(stats[i] & MDM_STAT_FREADY)) @@ -860,8 +859,7 @@ static struct kinetis_chip *kinetis_get_chip(struct target *target) static int kinetis_chip_options(struct kinetis_chip *k_chip, int argc, const char *argv[]) { - int i; - for (i = 0; i < argc; i++) { + for (int i = 0; i < argc; i++) { if (strcmp(argv[i], "-sim-base") == 0) { if (i + 1 < argc) k_chip->sim_base = strtoul(argv[++i], NULL, 0); @@ -933,7 +931,6 @@ static void kinetis_free_driver_priv(struct flash_bank *bank) static int kinetis_create_missing_banks(struct kinetis_chip *k_chip) { - unsigned bank_idx; unsigned num_blocks; struct kinetis_flash_bank *k_bank; struct flash_bank *bank; @@ -968,7 +965,7 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip) *p = '\0'; } - for (bank_idx = 1; bank_idx < num_blocks; bank_idx++) { + for (unsigned int bank_idx = 1; bank_idx < num_blocks; bank_idx++) { k_bank = &(k_chip->banks[bank_idx]); bank = k_bank->bank; @@ -1219,11 +1216,11 @@ static int kinetis_ftfx_clear_error(struct target *target) static int kinetis_ftfx_prepare(struct target *target) { - int result, i; + int result; uint8_t fstat; /* wait until busy */ - for (i = 0; i < 50; i++) { + for (unsigned int i = 0; i < 50; i++) { result = target_read_u8(target, FTFx_FSTAT, &fstat); if (result != ERROR_OK) return result; @@ -1343,8 +1340,6 @@ static int kinetis_write_block(struct flash_bank *bank, const uint8_t *buffer, static int kinetis_protect(struct flash_bank *bank, int set, int first, int last) { - int i; - if (allow_fcf_writes) { LOG_ERROR("Protection setting is possible with 'kinetis fcf_source protection' only!"); return ERROR_FAIL; @@ -1355,7 +1350,7 @@ static int kinetis_protect(struct flash_bank *bank, int set, int first, int last return ERROR_FLASH_BANK_INVALID; } - for (i = first; i < bank->num_prot_blocks && i <= last; i++) + for (int i = first; i < bank->num_prot_blocks && i <= last; i++) bank->prot_blocks[i].is_protected = set; LOG_INFO("Protection bits will be written at the next FCF sector erase or write."); @@ -1369,7 +1364,7 @@ static int kinetis_protect_check(struct flash_bank *bank) { struct kinetis_flash_bank *k_bank = bank->driver_priv; int result; - int i, b; + int b; uint32_t fprot; if (k_bank->flash_class == FC_PFLASH) { @@ -1397,7 +1392,7 @@ static int kinetis_protect_check(struct flash_bank *bank) } b = k_bank->protection_block; - for (i = 0; i < bank->num_prot_blocks; i++) { + for (int i = 0; i < bank->num_prot_blocks; i++) { if ((fprot >> b) & 1) bank->prot_blocks[i].is_protected = 0; else @@ -1415,8 +1410,6 @@ static int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf) uint32_t fprot = 0xffffffff; uint8_t fsec = 0xfe; /* set MCU unsecure */ uint8_t fdprot = 0xff; - int i; - unsigned bank_idx; unsigned num_blocks; uint32_t pflash_bit; uint8_t dflash_bit; @@ -1432,7 +1425,7 @@ static int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf) /* iterate over all kinetis banks */ /* current bank is bank 0, it contains FCF */ num_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks; - for (bank_idx = 0; bank_idx < num_blocks; bank_idx++) { + for (unsigned int bank_idx = 0; bank_idx < num_blocks; bank_idx++) { k_bank = &(k_chip->banks[bank_idx]); bank_iter = k_bank->bank; @@ -1446,7 +1439,7 @@ static int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf) assert(bank_iter->prot_blocks); if (k_bank->flash_class == FC_PFLASH) { - for (i = 0; i < bank_iter->num_prot_blocks; i++) { + for (int i = 0; i < bank_iter->num_prot_blocks; i++) { if (bank_iter->prot_blocks[i].is_protected == 1) fprot &= ~pflash_bit; @@ -1454,7 +1447,7 @@ static int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf) } } else if (k_bank->flash_class == FC_FLEX_NVM) { - for (i = 0; i < bank_iter->num_prot_blocks; i++) { + for (int i = 0; i < bank_iter->num_prot_blocks; i++) { if (bank_iter->prot_blocks[i].is_protected == 1) fdprot &= ~dflash_bit; @@ -1542,7 +1535,7 @@ static int kinetis_read_pmstat(struct kinetis_chip *k_chip, uint8_t *pmstat) static int kinetis_check_run_mode(struct kinetis_chip *k_chip) { - int result, i; + int result; uint8_t pmstat; struct target *target; @@ -1580,7 +1573,7 @@ static int kinetis_check_run_mode(struct kinetis_chip *k_chip) if (result != ERROR_OK) return result; - for (i = 100; i; i--) { + for (unsigned int i = 100; i > 0; i--) { result = kinetis_read_pmstat(k_chip, &pmstat); if (result != ERROR_OK) return result; @@ -1625,7 +1618,7 @@ static void kinetis_invalidate_flash_cache(struct kinetis_chip *k_chip) static int kinetis_erase(struct flash_bank *bank, int first, int last) { - int result, i; + int result; struct kinetis_flash_bank *k_bank = bank->driver_priv; struct kinetis_chip *k_chip = k_bank->k_chip; @@ -1646,7 +1639,7 @@ static int kinetis_erase(struct flash_bank *bank, int first, int last) * requested erase is PFlash or NVM and encompasses the entire * block. Should be quicker. */ - for (i = first; i <= last; i++) { + for (int i = first; i <= last; i++) { /* set command and sector address */ result = kinetis_ftfx_command(bank->target, FTFx_CMD_SECTERASE, k_bank->prog_base + bank->sectors[i].offset, 0, 0, 0, 0, 0, 0, 0, 0, NULL); @@ -1810,25 +1803,26 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { - int result, fallback = 0; + int result; + bool fallback = false; struct kinetis_flash_bank *k_bank = bank->driver_priv; struct kinetis_chip *k_chip = k_bank->k_chip; if (!(k_chip->flash_support & FS_PROGRAM_SECTOR)) { /* fallback to longword write */ - fallback = 1; + fallback = true; LOG_INFO("This device supports Program Longword execution only."); } else { result = kinetis_make_ram_ready(bank->target); if (result != ERROR_OK) { - fallback = 1; + fallback = true; LOG_WARNING("FlexRAM not ready, fallback to slow longword write."); } } LOG_DEBUG("flash write @ " TARGET_ADDR_FMT, bank->base + offset); - if (fallback == 0) { + if (!fallback) { /* program section command */ kinetis_write_sections(bank, buffer, offset, count); } else if (k_chip->flash_support & FS_PROGRAM_LONGWORD) { @@ -2020,7 +2014,6 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip) unsigned familyid = 0, subfamid = 0; unsigned cpu_mhz = 120; - unsigned idx; bool use_nvm_marking = false; char flash_marking[12], nvm_marking[2]; char name[40]; @@ -2115,7 +2108,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip) LOG_ERROR("Unsupported K-family FAMID"); } - for (idx = 0; idx < ARRAY_SIZE(kinetis_types_old); idx++) { + for (size_t idx = 0; idx < ARRAY_SIZE(kinetis_types_old); idx++) { if (kinetis_types_old[idx].sdid == mcu_type) { strcpy(name, kinetis_types_old[idx].name); use_nvm_marking = true; @@ -2621,7 +2614,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip) static int kinetis_probe(struct flash_bank *bank) { - int result, i; + int result; uint8_t fcfg2_maxaddr0, fcfg2_pflsh, fcfg2_maxaddr1; unsigned num_blocks, first_nvm_bank; uint32_t size_k; @@ -2673,6 +2666,7 @@ static int kinetis_probe(struct flash_bank *bank) if (k_chip->dflash_size == 0) { k_bank->protection_size = 0; } else { + int i; for (i = k_chip->dflash_size; ~i & 1; i >>= 1) ; if (i == 1) @@ -2829,8 +2823,7 @@ static int kinetis_blank_check(struct flash_bank *bank) if (block_dirty) { /* the whole bank is not erased, check sector-by-sector */ - int i; - for (i = 0; i < bank->num_sectors; i++) { + for (int i = 0; i < bank->num_sectors; i++) { /* normal margin */ result = kinetis_ftfx_command(bank->target, FTFx_CMD_SECTSTAT, k_bank->prog_base + bank->sectors[i].offset, @@ -2846,8 +2839,7 @@ static int kinetis_blank_check(struct flash_bank *bank) } } else { /* the whole bank is erased, update all sectors */ - int i; - for (i = 0; i < bank->num_sectors; i++) + for (int i = 0; i < bank->num_sectors; i++) bank->sectors[i].is_erased = 1; } } else { From 22797616aca1eaf378760fd255a0b84da979cf3a Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 20 Feb 2020 21:54:18 +0100 Subject: [PATCH 284/354] flash/nor/avrf: Minor code cleanups Change-Id: I64aa8e41f336584b524445e0ee7f986a0032852a Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5461 Tested-by: jenkins Reviewed-by: Lars Poeschel Reviewed-by: Antonio Borneo --- src/flash/nor/avrf.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/flash/nor/avrf.c b/src/flash/nor/avrf.c index de8c563c6..93f6872bd 100644 --- a/src/flash/nor/avrf.c +++ b/src/flash/nor/avrf.c @@ -58,7 +58,7 @@ struct avrf_type { struct avrf_flash_bank { int ppage_size; - int probed; + bool probed; }; static const struct avrf_type avft_chips_info[] = { @@ -149,7 +149,7 @@ static int avr_jtagprg_writeflashpage(struct avr_common *avr, uint32_t addr, uint32_t page_size) { - uint32_t i, poll_value; + uint32_t poll_value; avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS); avr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2310, AVR_JTAG_REG_ProgrammingCommand_Len); @@ -175,7 +175,7 @@ static int avr_jtagprg_writeflashpage(struct avr_common *avr, avr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_PAGELOAD); - for (i = 0; i < page_size; i++) { + for (uint32_t i = 0; i < page_size; i++) { if (i < buf_size) avr_jtag_senddat(avr->jtag_info.tap, NULL, page_buf[i], 8); else @@ -213,7 +213,7 @@ FLASH_BANK_COMMAND_HANDLER(avrf_flash_bank_command) avrf_info = malloc(sizeof(struct avrf_flash_bank)); bank->driver_priv = avrf_info; - avrf_info->probed = 0; + avrf_info->probed = false; return ERROR_OK; } @@ -304,7 +304,6 @@ static int avrf_probe(struct flash_bank *bank) struct avrf_flash_bank *avrf_info = bank->driver_priv; struct avr_common *avr = target->arch_info; const struct avrf_type *avr_info = NULL; - int i; uint32_t device_id; if (bank->target->state != TARGET_HALTED) { @@ -312,7 +311,7 @@ static int avrf_probe(struct flash_bank *bank) return ERROR_TARGET_NOT_HALTED; } - avrf_info->probed = 0; + avrf_info->probed = false; avr_jtag_read_jtagid(avr, &device_id); if (ERROR_OK != mcu_execute_queue()) @@ -324,7 +323,7 @@ static int avrf_probe(struct flash_bank *bank) EXTRACT_MFG(device_id), 0x1F); - for (i = 0; i < (int)ARRAY_SIZE(avft_chips_info); i++) { + for (size_t i = 0; i < ARRAY_SIZE(avft_chips_info); i++) { if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id)) { avr_info = &avft_chips_info[i]; LOG_INFO("target device is %s", avr_info->name); @@ -344,20 +343,20 @@ static int avrf_probe(struct flash_bank *bank) bank->num_sectors = avr_info->flash_page_num; bank->sectors = malloc(sizeof(struct flash_sector) * avr_info->flash_page_num); - for (i = 0; i < avr_info->flash_page_num; i++) { + for (int i = 0; i < avr_info->flash_page_num; i++) { bank->sectors[i].offset = i * avr_info->flash_page_size; bank->sectors[i].size = avr_info->flash_page_size; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = -1; } - avrf_info->probed = 1; + avrf_info->probed = true; return ERROR_OK; } else { /* chip not supported */ LOG_ERROR("0x%" PRIx32 " is not support for avr", EXTRACT_PART(device_id)); - avrf_info->probed = 1; + avrf_info->probed = true; return ERROR_FAIL; } } @@ -375,7 +374,6 @@ static int avrf_info(struct flash_bank *bank, char *buf, int buf_size) struct target *target = bank->target; struct avr_common *avr = target->arch_info; const struct avrf_type *avr_info = NULL; - int i; uint32_t device_id; if (bank->target->state != TARGET_HALTED) { @@ -393,7 +391,7 @@ static int avrf_info(struct flash_bank *bank, char *buf, int buf_size) EXTRACT_MFG(device_id), 0x1F); - for (i = 0; i < (int)ARRAY_SIZE(avft_chips_info); i++) { + for (size_t i = 0; i < ARRAY_SIZE(avft_chips_info); i++) { if (avft_chips_info[i].chip_id == EXTRACT_PART(device_id)) { avr_info = &avft_chips_info[i]; LOG_INFO("target device is %s", avr_info->name); @@ -434,8 +432,6 @@ static int avrf_mass_erase(struct flash_bank *bank) COMMAND_HANDLER(avrf_handle_mass_erase_command) { - int i; - if (CMD_ARGC < 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -446,7 +442,7 @@ COMMAND_HANDLER(avrf_handle_mass_erase_command) if (avrf_mass_erase(bank) == ERROR_OK) { /* set all sectors as erased */ - for (i = 0; i < bank->num_sectors; i++) + for (int i = 0; i < bank->num_sectors; i++) bank->sectors[i].is_erased = 1; command_print(CMD, "avr mass erase complete"); From 6f91aae1592c5ca8707b22a7cf0b54979f579cae Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Sun, 26 Apr 2020 20:21:16 +0100 Subject: [PATCH 285/354] hla: remove unused hl_interface_param_s.api Change-Id: I90a23293c7e3a6067d56e56d186f9f452af7c15e Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5611 Reviewed-by: Antonio Borneo Tested-by: jenkins --- src/jtag/hla/hla_interface.c | 2 +- src/jtag/hla/hla_interface.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index 95233c0d7..6d5cdc5e7 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -35,7 +35,7 @@ #include -static struct hl_interface_s hl_if = { {0, 0, { 0 }, { 0 }, 0, HL_TRANSPORT_UNKNOWN, false, -1}, 0, 0 }; +static struct hl_interface_s hl_if = { {0, 0, { 0 }, { 0 }, HL_TRANSPORT_UNKNOWN, false, -1}, 0, 0 }; int hl_interface_open(enum hl_transports tr) { diff --git a/src/jtag/hla/hla_interface.h b/src/jtag/hla/hla_interface.h index 262025e98..b6e4a8b92 100644 --- a/src/jtag/hla/hla_interface.h +++ b/src/jtag/hla/hla_interface.h @@ -41,8 +41,6 @@ struct hl_interface_param_s { /** List of recognised PIDs */ uint16_t pid[HLA_MAX_USB_IDS + 1]; /** */ - unsigned api; - /** */ enum hl_transports transport; /** */ bool connect_under_reset; From 82f71aa274fbb45cd3e86bce08e01c7015b05a59 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Wed, 13 Apr 2016 13:36:26 +0200 Subject: [PATCH 286/354] server/telnet: Fix history output Restore the prompt after the "history" command is invoked. Change-Id: I3d0744abbc58e82b039e06f21675efa180e8e1b0 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/3414 Tested-by: jenkins Reviewed-by: Marc Schink Reviewed-by: Antonio Borneo --- src/server/telnet_server.c | 50 ++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/server/telnet_server.c b/src/server/telnet_server.c index bfabae833..d0583a9b3 100644 --- a/src/server/telnet_server.c +++ b/src/server/telnet_server.c @@ -312,6 +312,36 @@ static void telnet_history_down(struct connection *connection) telnet_history_go(connection, next_history); } +static int telnet_history_print(struct connection *connection) +{ + struct telnet_connection *tc; + + tc = connection->priv; + + for (size_t i = 1; i < TELNET_LINE_HISTORY_SIZE; i++) { + char *line; + + /* + * The tc->next_history line contains empty string (unless NULL), thus + * it is not printed. + */ + line = tc->history[(tc->next_history + i) % TELNET_LINE_HISTORY_SIZE]; + + if (line) { + telnet_write(connection, line, strlen(line)); + telnet_write(connection, "\r\n\x00", 3); + } + } + + tc->line_size = 0; + tc->line_cursor = 0; + + /* The prompt is always placed at the line beginning. */ + telnet_write(connection, "\r", 1); + + return telnet_prompt(connection); +} + static void telnet_move_cursor(struct connection *connection, size_t pos) { struct telnet_connection *tc; @@ -407,21 +437,11 @@ static int telnet_input(struct connection *connection) telnet_write(connection, "\r\n\x00", 3); if (strcmp(t_con->line, "history") == 0) { - size_t i; - for (i = 1; i < TELNET_LINE_HISTORY_SIZE; i++) { - /* the t_con->next_history line contains empty string - * (unless NULL), thus it is not printed */ - char *history_line = t_con->history[(t_con-> - next_history + i) % - TELNET_LINE_HISTORY_SIZE]; - if (history_line) { - telnet_write(connection, history_line, - strlen(history_line)); - telnet_write(connection, "\r\n\x00", 3); - } - } - t_con->line_size = 0; - t_con->line_cursor = 0; + retval = telnet_history_print(connection); + + if (retval != ERROR_OK) + return retval; + continue; } From fdad56ecb02e072245bbcf86d9a6b506149c6a25 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Tue, 28 Jan 2020 21:40:37 +0100 Subject: [PATCH 287/354] flash/nor/efm32: Some small code cleanups Change-Id: I547970ce31435f75bae01d6d2cc96ebc9c15588c Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5420 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/efm32.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/flash/nor/efm32.c b/src/flash/nor/efm32.c index 9cdc32573..fe4ddd47e 100644 --- a/src/flash/nor/efm32.c +++ b/src/flash/nor/efm32.c @@ -99,7 +99,7 @@ struct efm32_family_data { }; struct efm32x_flash_bank { - int probed; + bool probed; uint32_t lb_page[LOCKBITS_PAGE_SZ/4]; uint32_t reg_base; uint32_t reg_lock; @@ -351,7 +351,7 @@ FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command) efm32x_info = malloc(sizeof(struct efm32x_flash_bank)); bank->driver_priv = efm32x_info; - efm32x_info->probed = 0; + efm32x_info->probed = false; memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ); return ERROR_OK; @@ -470,7 +470,6 @@ static int efm32x_erase_page(struct flash_bank *bank, uint32_t addr) static int efm32x_erase(struct flash_bank *bank, int first, int last) { struct target *target = bank->target; - int i = 0; int ret = 0; if (TARGET_HALTED != target->state) { @@ -485,7 +484,7 @@ static int efm32x_erase(struct flash_bank *bank, int first, int last) return ret; } - for (i = first; i <= last; i++) { + for (int i = first; i <= last; i++) { ret = efm32x_erase_page(bank, bank->sectors[i].offset); if (ERROR_OK != ret) LOG_ERROR("Failed to erase page %d", i); @@ -501,7 +500,6 @@ static int efm32x_read_lock_data(struct flash_bank *bank) { struct efm32x_flash_bank *efm32x_info = bank->driver_priv; struct target *target = bank->target; - int i = 0; int data_size = 0; uint32_t *ptr = NULL; int ret = 0; @@ -513,7 +511,7 @@ static int efm32x_read_lock_data(struct flash_bank *bank) ptr = efm32x_info->lb_page; - for (i = 0; i < data_size; i++, ptr++) { + for (int i = 0; i < data_size; i++, ptr++) { ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+i*4, ptr); if (ERROR_OK != ret) { LOG_ERROR("Failed to read PLW %d", i); @@ -619,7 +617,6 @@ static int efm32x_set_page_lock(struct flash_bank *bank, size_t page, int set) static int efm32x_protect(struct flash_bank *bank, int set, int first, int last) { struct target *target = bank->target; - int i = 0; int ret = 0; if (!set) { @@ -632,7 +629,7 @@ static int efm32x_protect(struct flash_bank *bank, int set, int first, int last) return ERROR_TARGET_NOT_HALTED; } - for (i = first; i <= last; i++) { + for (int i = first; i <= last; i++) { ret = efm32x_set_page_lock(bank, i, set); if (ERROR_OK != ret) { LOG_ERROR("Failed to set lock on page %d", i); @@ -963,11 +960,10 @@ static int efm32x_probe(struct flash_bank *bank) struct efm32x_flash_bank *efm32x_info = bank->driver_priv; struct efm32_info efm32_mcu_info; int ret; - int i; uint32_t base_address = 0x00000000; char buf[256]; - efm32x_info->probed = 0; + efm32x_info->probed = false; memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ); ret = efm32x_read_info(bank, &efm32_mcu_info); @@ -1006,14 +1002,14 @@ static int efm32x_probe(struct flash_bank *bank) bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); - for (i = 0; i < num_pages; i++) { + for (int i = 0; i < num_pages; i++) { bank->sectors[i].offset = i * efm32_mcu_info.page_size; bank->sectors[i].size = efm32_mcu_info.page_size; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } - efm32x_info->probed = 1; + efm32x_info->probed = true; return ERROR_OK; } @@ -1030,7 +1026,6 @@ static int efm32x_protect_check(struct flash_bank *bank) { struct target *target = bank->target; int ret = 0; - int i = 0; if (target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -1045,7 +1040,7 @@ static int efm32x_protect_check(struct flash_bank *bank) assert(NULL != bank->sectors); - for (i = 0; i < bank->num_sectors; i++) + for (int i = 0; i < bank->num_sectors; i++) bank->sectors[i].is_protected = efm32x_get_page_lock(bank, i); return ERROR_OK; From 2a8303b0bd1ea10b1a60891cbff24d717a985f6f Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 5 May 2020 18:11:47 +0200 Subject: [PATCH 288/354] tcl: stm32mp15x: fix "reset halt" on CM4 in engineering boot The state machine of cortex-m have to pass through a set of state before it get in "halted". Add one more "arp_poll" to achieve the proper state during a "reset halt" command in engineering boot. Change-Id: I90828bf20ef75bd4018f8b911f727ae69c4d6e8f Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5649 Tested-by: jenkins Reviewed-by: Richard Braun --- tcl/target/stm32mp15x.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcl/target/stm32mp15x.cfg b/tcl/target/stm32mp15x.cfg index a11f6665e..f2ba94eec 100644 --- a/tcl/target/stm32mp15x.cfg +++ b/tcl/target/stm32mp15x.cfg @@ -114,7 +114,7 @@ $_CHIPNAME.ap2 configure -event reset-deassert-pre {dbgmcu_enable_debug} $_CHIPNAME.cpu0 configure -event reset-deassert-pre {$::_CHIPNAME.cpu0 arp_examine} $_CHIPNAME.cpu1 configure -event reset-deassert-pre {$::_CHIPNAME.cpu1 arp_examine allow-defer} $_CHIPNAME.cpu0 configure -event reset-deassert-post {toggle_cpu0_dbg_claim0} -$_CHIPNAME.cm4 configure -event reset-deassert-post {$::_CHIPNAME.cm4 arp_examine;if {[$::_CHIPNAME.ap2 curstate] == "halted"} {$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_halt}} +$_CHIPNAME.cm4 configure -event reset-deassert-post {$::_CHIPNAME.cm4 arp_examine;if {[$::_CHIPNAME.ap2 curstate] == "halted"} {$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_halt}} $_CHIPNAME.ap1 configure -event examine-start {dap init} $_CHIPNAME.ap2 configure -event examine-start {dbgmcu_enable_debug} $_CHIPNAME.cpu0 configure -event examine-end {detect_cpu1} From 8807a5937e5fe5d09828c3e535beafb48e171621 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 1 May 2020 18:30:00 +0200 Subject: [PATCH 289/354] helper/command: register all commands through register_commands() The commands "ocd_find" and "capture" are registered directly through the jim API, instead of the common way to describe them in a struct command_registration that is then passed to the helper register_commands(). This cause the two commands above to not have either "help" nor "usage" string nor a properly identified "mode". Since the following line registers the commands listed in struct command_builtin_handlers, simply add the two commands above in the same struct. Change-Id: Id6ee11dac3b18364deeed65ee8e18ad80152750a Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5644 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/helper/command.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index ec07a5fef..0882ecd58 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -1229,6 +1229,21 @@ static const struct command_registration command_subcommand_handlers[] = { }; static const struct command_registration command_builtin_handlers[] = { + { + .name = "ocd_find", + .mode = COMMAND_ANY, + .jim_handler = jim_find, + .help = "find full path to file", + .usage = "file", + }, + { + .name = "capture", + .mode = COMMAND_ANY, + .jim_handler = jim_capture, + .help = "Capture progress output and return as tcl return value. If the " + "progress output was empty, return tcl return value.", + .usage = "command", + }, { .name = "echo", .handler = jim_echo, @@ -1339,9 +1354,6 @@ struct command_context *command_init(const char *startup_tcl, Jim_Interp *interp Jim_SetGlobalVariableStr(interp, "ocd_HOSTOS", Jim_NewStringObj(interp, HostOs, strlen(HostOs))); - Jim_CreateCommand(interp, "ocd_find", jim_find, NULL, NULL); - Jim_CreateCommand(interp, "capture", jim_capture, NULL, NULL); - register_commands(context, NULL, command_builtin_handlers); Jim_SetAssocData(interp, "context", NULL, context); From 4738a55da416176542efa1b554020de275a5b4e5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 27 Apr 2020 23:19:14 +0200 Subject: [PATCH 290/354] helper/ioutil: silence gcc-8 on strncpy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting from version 8, gcc issues a warning if strncpy could be able to truncate a string (so without adding the zero-termination char in destination) by copying exactly "size" char from a source string not shorter than "size". Such truncation from strncpy could actually be the desired code behaviour, but the way to silent gcc only locally (without global disabling with -Wno-stringop-truncation) through pragma has other side effects on portability. In current code, the source string is always "eth0", because has been checked right above. So this is a false positive from gcc, being always strlen("eth0") < 16, the sizeof(ifreq.ifr_name). Silent gcc by decrementing the "size" and remove: error: ‘strncpy’ specified bound 16 equals destination size [-Werror=stringop-truncation] This file is only optionally compiled together with ZY1000 driver with --enable-zy1000 --enable-ioutil. This combination is not checked in jenkins, so the error passed unnoticed. Plus, the configure flags above are both deprecated! Change-Id: I229e66227cfd3513139feeaffa47a6e1ec00767b Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5631 Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- src/helper/ioutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helper/ioutil.c b/src/helper/ioutil.c index d4f39e242..c103ce173 100644 --- a/src/helper/ioutil.c +++ b/src/helper/ioutil.c @@ -403,7 +403,7 @@ static int ioutil_Jim_Command_mac(Jim_Interp *interp, int argc, { if (strcmp("eth0", ifr->ifr_name) != 0) continue; - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name) - 1); if (ioctl(SockFD, SIOCGIFHWADDR, &ifreq) < 0) { close(SockFD); return JIM_ERR; From 307ee6db473b3e92597ee69863f5428a37a8a941 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 27 Apr 2020 16:52:31 +0200 Subject: [PATCH 291/354] doc: fix texinfo warning on @deffn not at the line beginning Commit 87a4158acf56 ("drivers: xds110: Clean up command syntax and documentation") does not follow the documentation structure that lists the adapters in cpt 2 "Debug Adapter Hardware" then lists the adapter commands in cpt 8.2 "Interface Drivers"; it puts all in cpt 2. While doing that, uses an incorrect texinfo syntax that causes the following warnings at compile time: doc/openocd.texi:543: warning: @deffn should only appear at the beginning of a line doc/openocd.texi:547: warning: @deffn should only appear at the beginning of a line doc/openocd.texi:552: warning: @deffn should only appear at the beginning of a line Move the documentation of xds110 commands in the proper chapter and fix the texinfo syntax. Change-Id: I0b3f0fe0c687f194bb02e2d81aca86fcd4fdd718 Signed-off-by: Antonio Borneo Fixes: 87a4158acf56 ("drivers: xds110: Clean up command syntax and documentation") Reviewed-on: http://openocd.zylin.com/5613 Tested-by: jenkins Reviewed-by: Andreas Fritiofson Reviewed-by: Edward Fewell --- doc/openocd.texi | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index 2dbe770ad..f3f963ecd 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -536,24 +536,6 @@ debuggers to ARM Cortex based targets @url{http://www.keil.com/support/man/docs/ @* Link: @url{http://www.keil.com/ulink1/} @item @b{TI XDS110 Debug Probe} -@* The XDS110 is included as the embedded debug probe on many Texas Instruments -LaunchPad evaluation boards. The XDS110 is also available as a stand-alone USB -debug probe with the added capability to supply power to the target board. The -following commands are supported by the XDS110 driver: -@*@deffn {Config Command} {xds110 serial} serial_string -Specifies the serial number of which XDS110 probe to use. Otherwise, the first -XDS110 found will be used. -@end deffn -@*@deffn {Config Command} {xds110 supply} voltage_in_millivolts -Available only on the XDS110 stand-alone probe. Sets the voltage level of the -XDS110 power supply. A value of 0 leaves the supply off. Otherwise, the supply -can be set to any value in the range 1800 to 3600 millivolts. -@end deffn -@*@deffn {Command} {xds110 info} -Displays information about the connected XDS110 debug probe (e.g. firmware -version). -@end deffn -@* Further information can be found at the following sites: @* Link: @url{https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds110.html} @* Link: @url{https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds_software_package_download.html#xds110-support-utilities} @end itemize @@ -3141,6 +3123,29 @@ opendous-jtag is a freely programmable USB adapter. This is the Keil ULINK v1 JTAG debugger. @end deffn +@deffn {Interface Driver} {xds110} +The XDS110 is included as the embedded debug probe on many Texas Instruments +LaunchPad evaluation boards. The XDS110 is also available as a stand-alone USB +debug probe with the added capability to supply power to the target board. The +following commands are supported by the XDS110 driver: + +@deffn {Config Command} {xds110 serial} serial_string +Specifies the serial number of which XDS110 probe to use. Otherwise, the first +XDS110 found will be used. +@end deffn + +@deffn {Config Command} {xds110 supply} voltage_in_millivolts +Available only on the XDS110 stand-alone probe. Sets the voltage level of the +XDS110 power supply. A value of 0 leaves the supply off. Otherwise, the supply +can be set to any value in the range 1800 to 3600 millivolts. +@end deffn + +@deffn {Command} {xds110 info} +Displays information about the connected XDS110 debug probe (e.g. firmware +version). +@end deffn +@end deffn + @deffn {Interface Driver} {xlnx_pcie_xvc} This driver supports the Xilinx Virtual Cable (XVC) over PCI Express. It is commonly found in Xilinx based PCI Express designs. It allows debugging From 3a28cdc7cb790e388f0e142510858bee0b642597 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 26 Apr 2020 01:39:16 +0200 Subject: [PATCH 292/354] doc: fix typo and spelling Identified by checkpatch script from Linux kernel v5.7-rc1 using the command find doc/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types TYPO_SPELLING --strict -f {} \; Change-Id: I1269ac966027439e16eb6e63179e43925bec37fa Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5614 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- doc/manual/target/mips.txt | 2 +- doc/openocd.texi | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/manual/target/mips.txt b/doc/manual/target/mips.txt index 5121d1276..25978a3d5 100644 --- a/doc/manual/target/mips.txt +++ b/doc/manual/target/mips.txt @@ -395,7 +395,7 @@ for (i = 0; i < count; i++) Each time when OpenOCD fills data to CPU (via dongle, via dmseg), CPU takes it and proceeds in executing the handler. However, since handler is in a assembly loop, CPU comes to next instruction which also fetches data from FASTDATA area. So it stalls. -Then OpenOCD fills the data again, from it's (OpenOCD's) loop. And this game continues untill all the data has been filled. +Then OpenOCD fills the data again, from it's (OpenOCD's) loop. And this game continues until all the data has been filled. After the last data has been given to CPU it sees that it reached the end address, so it proceeds with next instruction. However, this instruction do not point into dmseg, so CPU executes bunch of handler instructions (all prologue) and in the end jumps to MIPS32_PRACC_TEXT address. diff --git a/doc/openocd.texi b/doc/openocd.texi index f3f963ecd..ef77993ec 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -1474,7 +1474,7 @@ While the default is normally provided by the chip manufacturer, board files may need to distinguish between instances of a chip. @item @code{ENDIAN} ... By default @option{little} - although chips may hard-wire @option{big}. -Chips that can't change endianess don't need to use this variable. +Chips that can't change endianness don't need to use this variable. @item @code{CPUTAPID} ... When OpenOCD examines the JTAG chain, it can be told verify the chips against the JTAG IDCODE register. @@ -6459,7 +6459,7 @@ code. @end deffn @deffn Command {nrf5 info} -Decodes and shows informations from FICR and UICR registers. +Decodes and shows information from FICR and UICR registers. @end deffn @end deffn @@ -9774,7 +9774,7 @@ or a custom types described with @command{arc add-reg-type-[flags|struct]}. @item @code{-g} @* If specified then this is a "general" register. General registers are always read by OpenOCD on context save (when core has just been halted) and is always -transfered to GDB client in a response to g-packet. Contrary to this, +transferred to GDB client in a response to g-packet. Contrary to this, non-general registers are read and sent to GDB client on-demand. In general it is not recommended to apply this option to custom registers. @@ -9815,7 +9815,7 @@ therefore it is unsafe to use if that register can be operated by other means. @end deffn @deffn {Command} {arc jtag set-core-reg} regnum value -This command is similiar to @command{arc jtag set-aux-reg} but is for core +This command is similar to @command{arc jtag set-aux-reg} but is for core registers. @end deffn @@ -9827,7 +9827,7 @@ therefore it is unsafe to use if that register can be operated by other means. @end deffn @deffn {Command} {arc jtag get-core-reg} regnum -This command is similiar to @command{arc jtag get-aux-reg} but is for core +This command is similar to @command{arc jtag get-aux-reg} but is for core registers. @end deffn From 6d3cb807aaa60c4a4cd8ed49ae7860097bc1b3ce Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 26 Apr 2020 01:25:32 +0200 Subject: [PATCH 293/354] tcl: fix typo and spelling Identified by checkpatch script from Linux kernel v5.7-rc1 using the command find tcl/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types TYPO_SPELLING --strict -f {} \; Change-Id: I7b523f0ab5ec047ff167742a44c29984ac672cf4 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5615 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- tcl/board/alphascale_asm9260_ek.cfg | 2 +- tcl/board/at91sam9g20-ek.cfg | 2 +- tcl/board/icnova_imx53_sodimm.cfg | 2 +- tcl/board/imx35pdk.cfg | 4 ++-- tcl/board/imx53-m53evk.cfg | 2 +- tcl/board/imx53loco.cfg | 2 +- tcl/board/kindle2.cfg | 2 +- tcl/board/phone_se_j100i.cfg | 2 +- tcl/board/snps_em_sk.cfg | 2 +- tcl/board/snps_em_sk_v1.cfg | 2 +- tcl/board/snps_em_sk_v2.1.cfg | 2 +- tcl/board/snps_em_sk_v2.2.cfg | 2 +- tcl/board/steval_pcc010.cfg | 2 +- tcl/board/telo.cfg | 2 +- tcl/board/topas910.cfg | 2 +- tcl/board/topasa900.cfg | 2 +- tcl/board/twr-k60f120m.cfg | 2 +- tcl/board/twr-k60n512.cfg | 2 +- tcl/fpga/xilinx-xadc.cfg | 2 +- tcl/interface/ftdi/ft232h-module-swd.cfg | 2 +- tcl/mmr_helpers.tcl | 2 +- tcl/target/aducm360.cfg | 2 +- tcl/target/at91rm9200.cfg | 2 +- tcl/target/c100config.tcl | 2 +- tcl/target/c100helper.tcl | 12 ++++++------ tcl/target/dsp568013.cfg | 2 +- tcl/target/lpc2900.cfg | 2 +- tcl/target/lpc3131.cfg | 2 +- tcl/target/stellaris.cfg | 2 +- tcl/target/ti_cc3220sf.cfg | 2 +- tcl/tools/firmware-recovery.tcl | 2 +- 31 files changed, 37 insertions(+), 37 deletions(-) diff --git a/tcl/board/alphascale_asm9260_ek.cfg b/tcl/board/alphascale_asm9260_ek.cfg index 46e8a5b5b..1c126827f 100644 --- a/tcl/board/alphascale_asm9260_ek.cfg +++ b/tcl/board/alphascale_asm9260_ek.cfg @@ -23,7 +23,7 @@ $_TARGETNAME configure -event reset-init { # select PLL as main source mww 0x80040120 0x1 - # disable and enble main clk to update changes? + # disable and enable main clk to update changes? mww 0x80040124 0x0 mww 0x80040124 0x1 diff --git a/tcl/board/at91sam9g20-ek.cfg b/tcl/board/at91sam9g20-ek.cfg index e8018766a..9e0413a19 100644 --- a/tcl/board/at91sam9g20-ek.cfg +++ b/tcl/board/at91sam9g20-ek.cfg @@ -169,7 +169,7 @@ proc at91sam9g20_reset_init { } { # TRC = 9 cycles # TWR = 2 cycles # 9 column, 13 row, 4 banks - # refresh equal to or less then 7.8 us for commerical/industrial rated devices + # refresh equal to or less then 7.8 us for commercial/industrial rated devices # # Thus SDRAM_CR = 0xa6339279 diff --git a/tcl/board/icnova_imx53_sodimm.cfg b/tcl/board/icnova_imx53_sodimm.cfg index 2345ef120..dce9c470e 100644 --- a/tcl/board/icnova_imx53_sodimm.cfg +++ b/tcl/board/icnova_imx53_sodimm.cfg @@ -22,7 +22,7 @@ jtag_rclk 1000 $_TARGETNAME configure -event "reset-start" { jtag_rclk 1000 } $_TARGETNAME configure -event "reset-assert" { - echo "Reseting ...." + echo "Resetting ...." #cortex_a dbginit } diff --git a/tcl/board/imx35pdk.cfg b/tcl/board/imx35pdk.cfg index b5aa752fa..b81c0b01c 100644 --- a/tcl/board/imx35pdk.cfg +++ b/tcl/board/imx35pdk.cfg @@ -170,11 +170,11 @@ proc imx35pdk_init { } { mww 0xB8001010 0x00000304 #-------------------------------------------- - # Init 32-bit DDR2 memeory on CSD0 + # Init 32-bit DDR2 memory on CSD0 # COL=10-bit, ROW=13-bit, BA[1:0]=Addr[26:25] #-------------------------------------------- - # ESD_ESDCFG0 : set timing paramters + # ESD_ESDCFG0 : set timing parameters mww 0xB8001004 0x007ffC2f # ESD_ESDCTL0 : select Prechare-All mode diff --git a/tcl/board/imx53-m53evk.cfg b/tcl/board/imx53-m53evk.cfg index d18afc73a..baeb3cd9d 100644 --- a/tcl/board/imx53-m53evk.cfg +++ b/tcl/board/imx53-m53evk.cfg @@ -21,7 +21,7 @@ reset_config trst_and_srst separate trst_open_drain srst_open_drain adapter speed 6000 $_TARGETNAME configure -event "reset-assert" { - echo "Reseting ...." + echo "Resetting ...." #cortex_a dbginit } diff --git a/tcl/board/imx53loco.cfg b/tcl/board/imx53loco.cfg index 57473ead2..18caca574 100644 --- a/tcl/board/imx53loco.cfg +++ b/tcl/board/imx53loco.cfg @@ -23,7 +23,7 @@ $_TARGETNAME configure -event "reset-start" { jtag_rclk 1000 } #jtag_ntrst_delay 200 $_TARGETNAME configure -event "reset-assert" { - echo "Reseting ...." + echo "Resetting ...." #cortex_a dbginit } diff --git a/tcl/board/kindle2.cfg b/tcl/board/kindle2.cfg index fbb1022fd..a39f15c67 100644 --- a/tcl/board/kindle2.cfg +++ b/tcl/board/kindle2.cfg @@ -162,7 +162,7 @@ proc kindle2_sdram_init {} { # LPDDR1 Initialization script mww 0xb8001010 0x00000002 mww 0xb8001010 0x00000004 - # ESDCFG0: set timing paramters + # ESDCFG0: set timing parameters mww 0xb8001004 0x007fff7f # ESDCTL0: select Prechare-All mode mww 0xb8001000 0x92100000 diff --git a/tcl/board/phone_se_j100i.cfg b/tcl/board/phone_se_j100i.cfg index 632659027..ec61425ac 100644 --- a/tcl/board/phone_se_j100i.cfg +++ b/tcl/board/phone_se_j100i.cfg @@ -1,7 +1,7 @@ # # Sony Ericsson J100I Phone # -# more informations can be found on +# more information can be found on # http://bb.osmocom.org/trac/wiki/SonyEricssonJ100i # source [find target/ti_calypso.cfg] diff --git a/tcl/board/snps_em_sk.cfg b/tcl/board/snps_em_sk.cfg index 63c39a4d4..3d9340735 100644 --- a/tcl/board/snps_em_sk.cfg +++ b/tcl/board/snps_em_sk.cfg @@ -9,7 +9,7 @@ # # Configure JTAG cable -# EM Starter Kit has built-in FT2232 chip, which is similiar to Digilent HS-1. +# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1. source [find interface/ftdi/digilent-hs1.cfg] # 5MHz seems to work good with all cores that might happen in 2.x diff --git a/tcl/board/snps_em_sk_v1.cfg b/tcl/board/snps_em_sk_v1.cfg index 2e9d6025e..0c1539ee5 100644 --- a/tcl/board/snps_em_sk_v1.cfg +++ b/tcl/board/snps_em_sk_v1.cfg @@ -9,7 +9,7 @@ # # Configure JTAG cable -# EM Starter Kit has built-in FT2232 chip, which is similiar to Digilent HS-1. +# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1. source [find interface/ftdi/digilent-hs1.cfg] adapter speed 10000 diff --git a/tcl/board/snps_em_sk_v2.1.cfg b/tcl/board/snps_em_sk_v2.1.cfg index 5df8de571..c1fb232d5 100644 --- a/tcl/board/snps_em_sk_v2.1.cfg +++ b/tcl/board/snps_em_sk_v2.1.cfg @@ -9,7 +9,7 @@ # # Configure JTAG cable -# EM Starter Kit has built-in FT2232 chip, which is similiar to Digilent HS-1. +# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1. source [find interface/ftdi/digilent-hs1.cfg] # JTAG 10MHz is too fast for EM7D FPU in EM SK 2.1 which has core frequency diff --git a/tcl/board/snps_em_sk_v2.2.cfg b/tcl/board/snps_em_sk_v2.2.cfg index 7f3708e5c..674d9f65c 100644 --- a/tcl/board/snps_em_sk_v2.2.cfg +++ b/tcl/board/snps_em_sk_v2.2.cfg @@ -9,7 +9,7 @@ # # Configure JTAG cable -# EM Starter Kit has built-in FT2232 chip, which is similiar to Digilent HS-1. +# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1. source [find interface/ftdi/digilent-hs1.cfg] # EM11D reportedly requires 5 MHz. Other cores and board can work faster. diff --git a/tcl/board/steval_pcc010.cfg b/tcl/board/steval_pcc010.cfg index ddfdbb36f..94108d1ca 100644 --- a/tcl/board/steval_pcc010.cfg +++ b/tcl/board/steval_pcc010.cfg @@ -1,5 +1,5 @@ # Use for the STM207VG plug-in board (1 MiB Flash and 112+16 KiB Ram -# comming with the STEVAL-PCC010 board +# coming with the STEVAL-PCC010 board # http://www.st.com/internet/evalboard/product/251530.jsp # or any other board with only a STM32F2x in the JTAG chain diff --git a/tcl/board/telo.cfg b/tcl/board/telo.cfg index 05644f658..2c98ca3bd 100644 --- a/tcl/board/telo.cfg +++ b/tcl/board/telo.cfg @@ -1,5 +1,5 @@ source [find target/c100.cfg] -# basic register defintion for C100 +# basic register definition for C100 source [find target/c100regs.tcl] # board-config info source [find target/c100config.tcl] diff --git a/tcl/board/topas910.cfg b/tcl/board/topas910.cfg index 77084a96d..9f994c8ea 100644 --- a/tcl/board/topas910.cfg +++ b/tcl/board/topas910.cfg @@ -30,7 +30,7 @@ proc topas910_init { } { # Init SDRAM # _PMCDRV = 0x00000071; # // -# // Initialize SDRAM timing paramater +# // Initialize SDRAM timing parameter # // # _DMC_CAS_LATENCY = 0x00000006; # _DMC_T_DQSS = 0x00000000; diff --git a/tcl/board/topasa900.cfg b/tcl/board/topasa900.cfg index 5bd0e5e02..4fa63831b 100644 --- a/tcl/board/topasa900.cfg +++ b/tcl/board/topasa900.cfg @@ -37,7 +37,7 @@ proc topasa900_init { } { # Init SDRAM # _PMCDRV = 0x00000071; # // -# // Initialize SDRAM timing paramater +# // Initialize SDRAM timing parameter # // # _DMC_CAS_LATENCY = 0x00000006; # _DMC_T_DQSS = 0x00000000; diff --git a/tcl/board/twr-k60f120m.cfg b/tcl/board/twr-k60f120m.cfg index e96d04526..c4d87db26 100644 --- a/tcl/board/twr-k60f120m.cfg +++ b/tcl/board/twr-k60f120m.cfg @@ -5,7 +5,7 @@ source [find target/k60.cfg] $_TARGETNAME configure -event reset-init { - puts "-event reset-init occured" + puts "-event reset-init occurred" } # diff --git a/tcl/board/twr-k60n512.cfg b/tcl/board/twr-k60n512.cfg index d2312cf14..5babeb8c1 100644 --- a/tcl/board/twr-k60n512.cfg +++ b/tcl/board/twr-k60n512.cfg @@ -5,7 +5,7 @@ source [find target/k60.cfg] $_TARGETNAME configure -event reset-init { - puts "-event reset-init occured" + puts "-event reset-init occurred" } # diff --git a/tcl/fpga/xilinx-xadc.cfg b/tcl/fpga/xilinx-xadc.cfg index 38691045c..d4be4f541 100644 --- a/tcl/fpga/xilinx-xadc.cfg +++ b/tcl/fpga/xilinx-xadc.cfg @@ -5,7 +5,7 @@ # voltages. The XADC is available both from fabric as well as through the # JTAG TAP. # -# This code implements access throught the JTAG TAP. +# This code implements access through the JTAG TAP. # # https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf diff --git a/tcl/interface/ftdi/ft232h-module-swd.cfg b/tcl/interface/ftdi/ft232h-module-swd.cfg index e85640bc6..98a8c844f 100644 --- a/tcl/interface/ftdi/ft232h-module-swd.cfg +++ b/tcl/interface/ftdi/ft232h-module-swd.cfg @@ -15,7 +15,7 @@ ftdi_vid_pid 0x0403 0x6014 ftdi_layout_init 0x0030 0x003b # 0xfff8 0xfffb # Those signal are only required on some platforms or may required to be -# enabled explicitely (e.g. nrf5x chips). +# enabled explicitly (e.g. nrf5x chips). ftdi_layout_signal nSRST -data 0x0010 -oe 0x0010 ftdi_layout_signal nTRST -data 0x0020 -oe 0x0020 diff --git a/tcl/mmr_helpers.tcl b/tcl/mmr_helpers.tcl index ce116e459..e6b1c6704 100644 --- a/tcl/mmr_helpers.tcl +++ b/tcl/mmr_helpers.tcl @@ -28,7 +28,7 @@ proc show_mmr32_reg { NAME } { } -# Give: NAMES - an array of names accessable +# Give: NAMES - an array of names accessible # in the callers symbol-scope. # VAL - the bits to display. diff --git a/tcl/target/aducm360.cfg b/tcl/target/aducm360.cfg index caee9654e..b381728f1 100644 --- a/tcl/target/aducm360.cfg +++ b/tcl/target/aducm360.cfg @@ -10,7 +10,7 @@ if { [info exists CHIPNAME] } { set _CHIPNAME aducm360 } -# Endianess +# Endianness if { [info exists ENDIAN] } { set _ENDIAN $ENDIAN } else { diff --git a/tcl/target/at91rm9200.cfg b/tcl/target/at91rm9200.cfg index 2e8c1e091..3d9a8d9b5 100644 --- a/tcl/target/at91rm9200.cfg +++ b/tcl/target/at91rm9200.cfg @@ -28,7 +28,7 @@ if { $_CPUTAPID == 0x15b0203f } { echo "- ERROR: -" echo "- ERROR: In one position (0x05b0203f) it selects the -" echo "- ERROR: ARM CPU, in the other position (0x1b0203f) -" - echo "- ERROR: it selects boundry-scan not the ARM -" + echo "- ERROR: it selects boundary-scan not the ARM -" echo "- ERROR: -" echo "-------------------------------------------------------" } diff --git a/tcl/target/c100config.tcl b/tcl/target/c100config.tcl index a72a2fa84..53b2c5d48 100644 --- a/tcl/target/c100config.tcl +++ b/tcl/target/c100config.tcl @@ -1,5 +1,5 @@ -# board(-config) specfic parameters file. +# board(-config) specific parameters file. # set CFG_REFCLKFREQ [configC100 CFG_REFCLKFREQ] proc config {label} { diff --git a/tcl/target/c100helper.tcl b/tcl/target/c100helper.tcl index 9da3730b4..725ba709c 100644 --- a/tcl/target/c100helper.tcl +++ b/tcl/target/c100helper.tcl @@ -15,7 +15,7 @@ proc helpC100 {} { echo "12) ooma_board_detect: will show which version of Telo you have" echo "13) setupDDR2: will configure DDR2 controller, you must have PLLs configureg" echo "14) showDDR2: will show DDR2 config registers" - echo "15) showWatchdog: will show current regster config for watchdog" + echo "15) showWatchdog: will show current register config for watchdog" echo "16) reboot: will trigger watchdog and reboot Telo (hw reset)" echo "17) bootNOR: will boot Telo from NOR" echo "18) setupUART0: will configure UART0 for 115200 8N1, PLLs have to be confiured" @@ -176,7 +176,7 @@ proc setupAmbaClk {} { mmw $CLKCORE_AHB_CLK_CNTRL 0x0 0xFFFFFF mmw $CLKCORE_AHB_CLK_CNTRL [expr (($x << 16) + ($w << 8) + $y)] 0x0 # wait for PLL to lock - echo "Wating for Amba PLL to lock" + echo "Waiting for Amba PLL to lock" while {[expr [mrw $CLKCORE_PLL_STATUS] & $AHBCLK_PLL_LOCK] == 0} { sleep 1 } # remove the internal PLL bypass mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $AHB_PLL_BY_CTRL @@ -250,7 +250,7 @@ proc setupArmClk {} { mmw $CLKCORE_ARM_CLK_CNTRL 0x0 0xFFFFFF mmw $CLKCORE_ARM_CLK_CNTRL [expr (($x << 16) + ($w << 8) + $y)] 0x0 # wait for PLL to lock - echo "Wating for Amba PLL to lock" + echo "Waiting for Amba PLL to lock" while {[expr [mrw $CLKCORE_PLL_STATUS] & $FCLK_PLL_LOCK] == 0} { sleep 1 } # remove the internal PLL bypass mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $ARM_PLL_BY_CTRL @@ -300,7 +300,7 @@ proc setupDDR2 {} { # Memory setup register mww $MEMORY_MAX_ADDR [expr ($ddr_size - 1) + $MEMORY_BASE_ADDR] - # disbale ROM remap + # disable ROM remap mww $MEMORY_CR 0x0 # Take DDR controller out of reset mmw $BLOCK_RESET_REG $DDR_RST 0x0 @@ -486,7 +486,7 @@ proc reboot {} { set TIMER_WDT_CURRENT_COUNT [regs TIMER_WDT_CURRENT_COUNT] # allow the counter to count to high value before triggering - # this is because regsiter writes are slow over JTAG and + # this is because register writes are slow over JTAG and # I don't want to miss the high_bound==curr_count condition mww $TIMER_WDT_HIGH_BOUND 0xffffff mww $TIMER_WDT_CURRENT_COUNT 0x0 @@ -494,7 +494,7 @@ proc reboot {} { adapter speed 100 mww $TIMER_WDT_CONTROL 0x1 # wait until the reset - echo -n "Wating for watchdog to trigger..." + echo -n "Waiting for watchdog to trigger..." #while {[mrw $TIMER_WDT_CONTROL] == 1} { # echo [format "TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]] # sleep 1 diff --git a/tcl/target/dsp568013.cfg b/tcl/target/dsp568013.cfg index c0c1df2bc..40fa3c2b0 100644 --- a/tcl/target/dsp568013.cfg +++ b/tcl/target/dsp568013.cfg @@ -35,7 +35,7 @@ set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME # Setup the interesting tap -# Disable polling to be able to get idcode from core tap. If re enabled, can be re enabled, but it should be disabled to correctly unlock flash (operations requiere certain instruction to be in the IR register during reset, and polling would change this) +# Disable polling to be able to get idcode from core tap. If re enabled, can be re enabled, but it should be disabled to correctly unlock flash (operations require certain instruction to be in the IR register during reset, and polling would change this) jtag configure $_CHIPNAME.chp -event setup " jtag tapenable $_TARGETNAME poll off diff --git a/tcl/target/lpc2900.cfg b/tcl/target/lpc2900.cfg index 53677873a..523bc211f 100644 --- a/tcl/target/lpc2900.cfg +++ b/tcl/target/lpc2900.cfg @@ -14,7 +14,7 @@ if { [info exists CPUTAPID] } { if { [info exists HAS_ETB] } { } else { # Set default (no ETB). - # Show a warning, because this should have been configured explicitely. + # Show a warning, because this should have been configured explicitly. set HAS_ETB 0 # TODO: warning? } diff --git a/tcl/target/lpc3131.cfg b/tcl/target/lpc3131.cfg index 185c0aad8..d6f2cdbda 100644 --- a/tcl/target/lpc3131.cfg +++ b/tcl/target/lpc3131.cfg @@ -22,7 +22,7 @@ if { [info exists CPUTAPID] } { } # Scan Tap -# Wired to seperate STDO pin on the lpc3131, externally muxed to TDO on ea3131 module +# Wired to separate STDO pin on the lpc3131, externally muxed to TDO on ea3131 module # JTAGSEL pin must be 0 to activate, which reassigns arm tdo to a pass through. if { [info exists SJCTAPID] } { set _SJCTAPID $SJCTAPID diff --git a/tcl/target/stellaris.cfg b/tcl/target/stellaris.cfg index fb591c2bf..3cab4d140 100644 --- a/tcl/target/stellaris.cfg +++ b/tcl/target/stellaris.cfg @@ -164,7 +164,7 @@ $_TARGETNAME configure -event reset-start { } else { if {![using_hla]} { # Tempest and Firestorm default to using NVIC VECTRESET - # peripherals will need reseting manually, see proc reset_peripherals + # peripherals will need resetting manually, see proc reset_peripherals cortex_m reset_config vectreset } # reset peripherals, based on code in diff --git a/tcl/target/ti_cc3220sf.cfg b/tcl/target/ti_cc3220sf.cfg index 3e758e6ab..74269aa66 100644 --- a/tcl/target/ti_cc3220sf.cfg +++ b/tcl/target/ti_cc3220sf.cfg @@ -25,7 +25,7 @@ proc ocd_process_reset_inner { MODE } { soft_reset_halt - # Intialize MSP, PSP, and PC from vector table at flash 0x01000800 + # Initialize MSP, PSP, and PC from vector table at flash 0x01000800 mem2array boot 32 0x01000800 2 reg msp $boot(0) diff --git a/tcl/tools/firmware-recovery.tcl b/tcl/tools/firmware-recovery.tcl index 8b28656aa..9d7e0fce8 100644 --- a/tcl/tools/firmware-recovery.tcl +++ b/tcl/tools/firmware-recovery.tcl @@ -38,7 +38,7 @@ openocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\ shutdown } -# set default, can be overriden later +# set default, can be overridden later adapter speed 1000 proc get_partition { name } { From 5df5e89cf3caf02dc6f49a5d3c8aa8b1349a1dbf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 26 Apr 2020 01:07:27 +0200 Subject: [PATCH 294/354] tcl: remove trailing whitespace The script checkpatch available in new Linux kernel offers an experimental feature for automatically fix the code in place. While still experimental, the feature works quite well for simple fixes, like spacing. This patch has been created automatically with the script under review for inclusion in OpenOCD, using the command: find tcl/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types TRAILING_WHITESPACE --fix-inplace -f {} \; The patch only changes amount and position of whitespace, thus the following commands show empty diff git diff -w git log -w -p git log -w --stat Change-Id: Ie7e3a236f4db9c70019e3b3c7e851edbd3a9dd84 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5616 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- tcl/board/at91cap7a-stk-sdram.cfg | 20 ++++----- tcl/board/at91sam9g20-ek.cfg | 6 +-- tcl/board/hilscher_nxdb500sys.cfg | 2 +- tcl/board/hilscher_nxeb500hmi.cfg | 2 +- tcl/board/hilscher_nxsb100.cfg | 2 +- tcl/board/imx31pdk.cfg | 20 ++++----- tcl/board/imx35pdk.cfg | 70 +++++++++++++++---------------- tcl/board/mcb1700.cfg | 4 +- tcl/board/olimex_sam9_l9260.cfg | 42 +++++++++---------- tcl/board/phytec_lpc3250.cfg | 10 ++--- tcl/board/rsc-w910.cfg | 10 ++--- tcl/board/stm3210e_eval.cfg | 16 +++---- tcl/board/uptech_2410.cfg | 16 +++---- tcl/target/dsp56321.cfg | 4 +- tcl/target/dsp568013.cfg | 4 +- tcl/target/fm3.cfg | 4 +- tcl/target/imx.cfg | 2 +- tcl/target/ixp42x.cfg | 4 +- tcl/target/lpc2103.cfg | 2 +- tcl/target/lpc2124.cfg | 2 +- tcl/target/lpc2129.cfg | 2 +- tcl/target/lpc2148.cfg | 2 +- tcl/target/lpc2294.cfg | 4 +- tcl/target/lpc2378.cfg | 2 +- tcl/target/lpc2460.cfg | 2 +- tcl/target/lpc2478.cfg | 2 +- tcl/target/lpc2xxx.cfg | 2 +- tcl/target/lpc3131.cfg | 2 +- tcl/target/u8500.cfg | 20 ++++----- 29 files changed, 140 insertions(+), 140 deletions(-) diff --git a/tcl/board/at91cap7a-stk-sdram.cfg b/tcl/board/at91cap7a-stk-sdram.cfg index df91a6b0b..8395ba33b 100644 --- a/tcl/board/at91cap7a-stk-sdram.cfg +++ b/tcl/board/at91cap7a-stk-sdram.cfg @@ -43,13 +43,13 @@ proc wait_state {expression} { return } } - return -code 1 "Timed out" + return -code 1 "Timed out" } # Use a global variable here to be able to tinker interactively with # post reset jtag frequency. global post_reset_khz -# Danger!!!! Even 16MHz kinda works with this target, but +# Danger!!!! Even 16MHz kinda works with this target, but # it needs to be as low as 2000kHz to be stable. set post_reset_khz 2000 @@ -61,25 +61,25 @@ $_TARGETNAME configure -event reset-init { mww 0xfffffd08 0xa5000001 # Enable main oscillator mww 0xFFFFFc20 0x00000f01 - wait_state {expr {([peek32 0xFFFFFC68] & 0x1) == 0}} + wait_state {expr {([peek32 0xFFFFFC68] & 0x1) == 0}} # Set PLLA to 96MHz mww 0xFFFFFc28 0x20072801 - wait_state {expr {([peek32 0xFFFFFC68] & 0x2) == 0}} + wait_state {expr {([peek32 0xFFFFFC68] & 0x2) == 0}} # Select prescaler mww 0xFFFFFC30 0x00000004 - wait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}} + wait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}} # Select master clock to 48MHz mww 0xFFFFFC30 0x00000006 - wait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}} + wait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}} echo "Master clock ok." - + # Now that we're up and running, crank up speed! global post_reset_khz ; adapter speed $post_reset_khz - + echo "Configuring the SDRAM controller..." # Configure EBI Chip select for SDRAM @@ -95,7 +95,7 @@ $_TARGETNAME configure -event reset-init { # Configure SDRAMC CR mww 0xFFFFEA08 0xA63392F9 - + # NOP command mww 0xFFFFEA00 0x1 mww 0x20000000 0 @@ -151,7 +151,7 @@ $_TARGETNAME configure -event reset-init { #remap internal memory at address 0x0 mww 0xffffef00 0x3 - + echo "SDRAM configuration ok." } diff --git a/tcl/board/at91sam9g20-ek.cfg b/tcl/board/at91sam9g20-ek.cfg index 9e0413a19..03296c50e 100644 --- a/tcl/board/at91sam9g20-ek.cfg +++ b/tcl/board/at91sam9g20-ek.cfg @@ -139,13 +139,13 @@ proc at91sam9g20_reset_init { } { # (MT29F2G08AACWP) can be established by setting four registers in order: SMC_SETUP3, # SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3. Computing the exact values of these registers # is a little tedious to do here. If you have questions about how to do this, Atmel has - # a decent application note #6255B that covers this process. + # a decent application note #6255B that covers this process. mww 0xffffec30 0x00020002 ;# SMC_SETUP3 : 2 clock cycle setup for NRD and NWE mww 0xffffec34 0x04040404 ;# SMC_PULSE3 : 4 clock cycle pulse for all signals mww 0xffffec38 0x00070006 ;# SMC_CYCLE3 : 7 clock cycle NRD and 6 NWE cycle - mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW, - + mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW, + mww 0xffffe800 0x00000001 ;# ECC_CR : reset the ECC parity registers mww 0xffffe804 0x00000002 ;# ECC_MR : page size is 2112 words (word is 8 bits) diff --git a/tcl/board/hilscher_nxdb500sys.cfg b/tcl/board/hilscher_nxdb500sys.cfg index d71c4453b..20fa3ea03 100644 --- a/tcl/board/hilscher_nxdb500sys.cfg +++ b/tcl/board/hilscher_nxdb500sys.cfg @@ -17,7 +17,7 @@ $_TARGETNAME configure -event reset-init { arm7_9 dcc_downloads enable sdram_fix - + puts "Configuring SDRAM controller for paired K4S561632C (64MB) " mww 0x00100140 0 mww 0x00100144 0x03C13261 diff --git a/tcl/board/hilscher_nxeb500hmi.cfg b/tcl/board/hilscher_nxeb500hmi.cfg index aa3d58701..a51fa03bc 100644 --- a/tcl/board/hilscher_nxeb500hmi.cfg +++ b/tcl/board/hilscher_nxeb500hmi.cfg @@ -17,7 +17,7 @@ $_TARGETNAME configure -event reset-init { arm7_9 dcc_downloads disable sdram_fix - + puts "Configuring SDRAM controller for MT48LC8M32 (32MB) " mww 0x00100140 0 mww 0x00100144 0x03C23251 diff --git a/tcl/board/hilscher_nxsb100.cfg b/tcl/board/hilscher_nxsb100.cfg index 807e29200..c332beec0 100644 --- a/tcl/board/hilscher_nxsb100.cfg +++ b/tcl/board/hilscher_nxsb100.cfg @@ -17,7 +17,7 @@ $_TARGETNAME configure -event reset-init { arm7_9 dcc_downloads enable sdram_fix - + puts "Configuring SDRAM controller for MT48LC2M32 (8MB) " mww 0x00100140 0 mww 0x00100144 0x03C23251 diff --git a/tcl/board/imx31pdk.cfg b/tcl/board/imx31pdk.cfg index 502d40774..2dce157db 100644 --- a/tcl/board/imx31pdk.cfg +++ b/tcl/board/imx31pdk.cfg @@ -28,36 +28,36 @@ proc imx31pdk_init { } { mww 0x53FC0000 0x040 mww 0x53F80000 0x074B0B7D - + # 399MHz - 26MHz input, PD=1,MFI=7, MFN=27, MFD=40 #mww 0x53F80004 0xFF871D50 #mww 0x53F80010 0x00271C1B - + # Start 16 bit NorFlash Initialization on CS0 mww 0xb8002000 0x0000CC03 mww 0xb8002004 0xa0330D01 mww 0xb8002008 0x00220800 - + # Configure CPLD on CS4 mww 0xb8002040 0x0000DCF6 mww 0xb8002044 0x444A4541 mww 0xb8002048 0x44443302 - + # SDCLK mww 0x43FAC26C 0 - + # CAS mww 0x43FAC270 0 - + # RAS mww 0x43FAC274 0 - + # CS2 (CSD0) mww 0x43FAC27C 0x1000 - + # DQM3 mww 0x43FAC284 0 - + # DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2DC) mww 0x43FAC288 0 mww 0x43FAC28C 0 @@ -81,7 +81,7 @@ proc imx31pdk_init { } { mww 0x43FAC2D4 0 mww 0x43FAC2D8 0 mww 0x43FAC2DC 0 - + # Initialization script for 32 bit DDR on MX31 ADS mww 0xB8001010 0x00000004 mww 0xB8001004 0x006ac73a diff --git a/tcl/board/imx35pdk.cfg b/tcl/board/imx35pdk.cfg index b81c0b01c..2a7efaba7 100644 --- a/tcl/board/imx35pdk.cfg +++ b/tcl/board/imx35pdk.cfg @@ -8,9 +8,9 @@ $_TARGETNAME configure -event reset-init { imx35pdk_init } jtag_rclk 10 proc imx35pdk_init { } { - + imx3x_reset - + mww 0x43f00040 0x00000000 mww 0x43f00044 0x00000000 mww 0x43f00048 0x00000000 @@ -25,11 +25,11 @@ proc imx35pdk_init { } { mww 0x53f00050 0x00000000 mww 0x53f00000 0x77777777 mww 0x53f00004 0x77777777 - + # clock setup mww 0x53F80004 0x00821000 ;# first need to set IPU_HND_BYP mww 0x53F80004 0x00821000 ;#arm clock is 399Mhz and ahb clock is 133Mhz. - + #================================================= # WEIM config #================================================= @@ -45,14 +45,14 @@ proc imx35pdk_init { } { mww 0xB8002054 0x444a4541 # CS5A mww 0xB8002058 0x44443302 - + # IO SW PAD Control registers - setting of 0x0002 is high drive, mDDR mww 0x43FAC368 0x00000006 mww 0x43FAC36C 0x00000006 mww 0x43FAC370 0x00000006 mww 0x43FAC374 0x00000006 mww 0x43FAC378 0x00000006 - mww 0x43FAC37C 0x00000006 + mww 0x43FAC37C 0x00000006 mww 0x43FAC380 0x00000006 mww 0x43FAC384 0x00000006 mww 0x43FAC388 0x00000006 @@ -76,7 +76,7 @@ proc imx35pdk_init { } { mww 0x43FAC3D0 0x00000006 mww 0x43FAC3D4 0x00000006 mww 0x43FAC3D8 0x00000006 - + # DDR data bus SD 0 through 31 mww 0x43FAC3DC 0x00000082 mww 0x43FAC3E0 0x00000082 @@ -110,13 +110,13 @@ proc imx35pdk_init { } { mww 0x43FAC450 0x00000082 mww 0x43FAC454 0x00000082 mww 0x43FAC458 0x00000082 - + # DQM setup mww 0x43FAC45c 0x00000082 mww 0x43FAC460 0x00000082 mww 0x43FAC464 0x00000082 mww 0x43FAC468 0x00000082 - + mww 0x43FAC46c 0x00000006 mww 0x43FAC470 0x00000006 mww 0x43FAC474 0x00000006 @@ -130,30 +130,30 @@ proc imx35pdk_init { } { mww 0x43FAC494 0x00000006 mww 0x43FAC498 0x00000006 mww 0x43FAC49c 0x00000006 - mww 0x43FAC4A0 0x00000006 + mww 0x43FAC4A0 0x00000006 mww 0x43FAC4A4 0x00000006 ;# RAS mww 0x43FAC4A8 0x00000006 ;# CAS mww 0x43FAC4Ac 0x00000006 ;# SDWE mww 0x43FAC4B0 0x00000006 ;# SDCKE0 mww 0x43FAC4B4 0x00000006 ;# SDCKE1 mww 0x43FAC4B8 0x00000002 ;# SDCLK - + # SDQS0 through SDQS3 mww 0x43FAC4Bc 0x00000082 mww 0x43FAC4C0 0x00000082 mww 0x43FAC4C4 0x00000082 mww 0x43FAC4C8 0x00000082 - - + + # *================================================== # Initialization script for 32 bit DDR2 on RINGO 3DS # *================================================== - + #-------------------------------------------- # Init CCM #-------------------------------------------- mww 0x53F80028 0x7D000028 - + #-------------------------------------------- # Init IOMUX for JTAG #-------------------------------------------- @@ -164,24 +164,24 @@ proc imx35pdk_init { } { mww 0x43FAC5FC 0x000000F3 mww 0x43FAC600 0x000000F3 mww 0x43FAC604 0x000000F3 - - + + # ESD_MISC : enable DDR2 mww 0xB8001010 0x00000304 - + #-------------------------------------------- # Init 32-bit DDR2 memory on CSD0 # COL=10-bit, ROW=13-bit, BA[1:0]=Addr[26:25] #-------------------------------------------- - + # ESD_ESDCFG0 : set timing parameters - mww 0xB8001004 0x007ffC2f - + mww 0xB8001004 0x007ffC2f + # ESD_ESDCTL0 : select Prechare-All mode mww 0xB8001000 0x92220000 # DDR2 : Prechare-All mww 0x80000400 0x12345678 - + # ESD_ESDCTL0 : select Load-Mode-Register mode mww 0xB8001000 0xB2220000 # DDR2 : Load reg EMR2 @@ -192,18 +192,18 @@ proc imx35pdk_init { } { mwb 0x82000400 0xda # DDR2 : Load reg MR -- reset DLL mwb 0x80000333 0xda - + # ESD_ESDCTL0 : select Prechare-All mode mww 0xB8001000 0x92220000 # DDR2 : Prechare-All mwb 0x80000400 0x12345678 - + # ESD_ESDCTL0 : select Manual-Refresh mode mww 0xB8001000 0xA2220000 # DDR2 : Manual-Refresh 2 times mww 0x80000000 0x87654321 mww 0x80000000 0x87654321 - + # ESD_ESDCTL0 : select Load-Mode-Register mode mww 0xB8001000 0xB2220000 # DDR2 : Load reg MR -- CL=3, BL=8, end DLL reset @@ -212,19 +212,19 @@ proc imx35pdk_init { } { mwb 0x82000780 0xda # DDR2 : Load reg EMR1 -- OCD exit mwb 0x82000400 0xda ;# ODT disabled - + # ESD_ESDCTL0 : select normal-operation mode # DSIZ=32-bit, BL=8, COL=10-bit, ROW=13-bit # disable PWT & PRCT # disable Auto-Refresh mww 0xB8001000 0x82220080 - + ## ESD_ESDCTL0 : enable Auto-Refresh mww 0xB8001000 0x82228080 ## ESD_ESDCTL1 : enable Auto-Refresh mww 0xB8001008 0x00002000 - - + + #*********************************************** # Adjust the ESDCDLY5 register #*********************************************** @@ -233,20 +233,20 @@ proc imx35pdk_init { } { mww 0xB8001024 0x00F48000 ;# this is the default value mww 0xB8001028 0x00F48000 ;# this is the default value mww 0xB800102c 0x00F48000 ;# this is the default value - - + + #Then you can make force measure with the dedicated bit (Bit 7 at ESDMISC) mww 0xB8001010 0x00000384 # wait a while sleep 1000 # now clear the force measurement bit mww 0xB8001010 0x00000304 - + # dummy write to DDR memory to set DQS low mww 0x80000000 0x00000000 - + mww 0x30000100 0x0 mww 0x30000104 0x31024 - - + + } diff --git a/tcl/board/mcb1700.cfg b/tcl/board/mcb1700.cfg index 4954dab0a..01080a0b1 100644 --- a/tcl/board/mcb1700.cfg +++ b/tcl/board/mcb1700.cfg @@ -1,5 +1,5 @@ # Keil MCB1700 PCB with 1768 -# +# # Reset init script sets it to 100MHz set CCLK 100000 @@ -53,7 +53,7 @@ $_TARGETNAME configure -event reset-init { # Dividing CPU clock by 8 should be pretty conservative # - # + # global MCB1700_CCLK adapter speed [expr $MCB1700_CCLK / 8] diff --git a/tcl/board/olimex_sam9_l9260.cfg b/tcl/board/olimex_sam9_l9260.cfg index ad2f850a1..72dce87b1 100644 --- a/tcl/board/olimex_sam9_l9260.cfg +++ b/tcl/board/olimex_sam9_l9260.cfg @@ -23,15 +23,15 @@ $_TARGETNAME configure -event reset-start { # RCLK is not supported. jtag_rclk 5 halt - - # RSTC_MR : enable user reset, reset length is 64 slow clock cycles. MMU may + + # RSTC_MR : enable user reset, reset length is 64 slow clock cycles. MMU may # be enabled... use physical address. mww phys 0xfffffd08 0xa5000501 } $_TARGETNAME configure -event reset-init { mww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog - + ## # Clock configuration for 99.328 MHz main clock. ## @@ -45,23 +45,23 @@ $_TARGETNAME configure -event reset-init { mww 0xfffffc30 0x00000101 ;# PMC_MCKR : no scale on proc clock, master is proc / 2 sleep 10 ;# wait 10 ms mww 0xfffffc30 0x00000102 ;# PMC_MCKR : switch to PLLA (99.328 MHz) - + # Increase JTAG speed to 6 MHz if RCLK is not supported. jtag_rclk 6000 - + arm7_9 dcc_downloads enable ;# Enable faster DCC downloads. - + ## # SDRAM configuration for 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks. ## echo "Configuring SDRAM" mww 0xfffff870 0xffff0000 ;# PIOC_ASR : select peripheral function for D15..D31 mww 0xfffff804 0xffff0000 ;# PIOC_PDR : disable PIO function for D15..D31 - + mww 0xffffef1c 0x00010002 ;# EBI_CSA : assign EBI CS1 to SDRAM, VDDIOMSEL set for +3V3 memory - + mww 0xffffea08 0x85237259 ;# SDRAMC_CR : configure SDRAM for Samsung chips - + mww 0xffffea00 0x1 ;# SDRAMC_MR : issue NOP command mww 0x20000000 0 mww 0xffffea00 0x2 ;# SDRAMC_MR : issue an 'All Banks Precharge' command @@ -86,7 +86,7 @@ $_TARGETNAME configure -event reset-init { mww 0x20000000 0 mww 0xffffea00 0x0 ;# SDRAMC_MR : normal mode mww 0x20000000 0 - + mww 0xffffea04 0x2b6 ;# SDRAMC_TR : set refresh timer count to 7 us ## @@ -99,37 +99,37 @@ $_TARGETNAME configure -event reset-init { mww 0xfffff814 0x00002000 ;# PIOC_ODR : disable output on 13 mww 0xfffff830 0x00004000 ;# PIOC_SODR : set 14 to disable NAND mww 0xfffff864 0x00002000 ;# PIOC_PUER : enable pull-up on 13 - + mww 0xffffef1c 0x0001000A ;# EBI_CSA : assign EBI CS3 to NAND, same settings as before - + mww 0xffffec30 0x00010001 ;# SMC_SETUP3 : 1 clock cycle setup for NRD and NWE mww 0xffffec34 0x03030303 ;# SMC_PULSE3 : 3 clock cycle pulse for all signals mww 0xffffec38 0x00050005 ;# SMC_CYCLE3 : 5 clock cycle NRD and NWE cycle - mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW, + mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW, # 3 TDF cycles, no optimization - + mww 0xffffe800 0x00000001 ;# ECC_CR : reset the ECC parity registers mww 0xffffe804 0x00000002 ;# ECC_MR : page size is 2112 words (word is 8 bits) - + nand probe at91sam9260.flash - + ## # Dataflash configuration for 1 x Atmel AT45DB161D, 16Mbit ## echo "Setting up dataflash" - mww 0xfffff404 0x00000807 ;# PIOA_PDR : disable PIO function for 0(SPI0_MISO), 1(SPI0_MOSI), + mww 0xfffff404 0x00000807 ;# PIOA_PDR : disable PIO function for 0(SPI0_MISO), 1(SPI0_MOSI), # 2(SPI0_SPCK), and 11(SPI0_NPCS1) mww 0xfffff470 0x00000007 ;# PIOA_ASR : select peripheral A function for 0, 1, and 2 mww 0xfffff474 0x00000800 ;# PIOA_BSR : select peripheral B function for 11 mww 0xfffffc10 0x00001000 ;# PMC_PCER : enable SPI0 clock - + mww 0xfffc8000 0x00000080 ;# SPI0_CR : software reset SPI0 mww 0xfffc8000 0x00000080 ;# SPI0_CR : again to be sure mww 0xfffc8004 0x000F0011 ;# SPI0_MR : master mode with nothing selected - - mww 0xfffc8034 0x011a0302 ;# SPI0_CSR1 : capture on leading edge, 8-bits/tx. 33MHz baud, + + mww 0xfffc8034 0x011a0302 ;# SPI0_CSR1 : capture on leading edge, 8-bits/tx. 33MHz baud, # 250ns delay before SPCK, 250ns b/n tx - + mww 0xfffc8004 0x000D0011 ;# SPI0_MR : same config, select NPCS1 mww 0xfffc8000 0x00000001 ;# SPI0_CR : enable SPI0 } diff --git a/tcl/board/phytec_lpc3250.cfg b/tcl/board/phytec_lpc3250.cfg index 1c48f5df7..cee28cdd2 100644 --- a/tcl/board/phytec_lpc3250.cfg +++ b/tcl/board/phytec_lpc3250.cfg @@ -23,12 +23,12 @@ $_TARGETNAME configure -event reset-init { phytec_lpc3250_init } # Bare-bones initialization of core clocks and SDRAM proc phytec_lpc3250_init { } { - # Set clock dividers + # Set clock dividers # ARMCLK = 266.5 MHz # HCLK = 133.25 MHz # PERIPHCLK = 13.325 MHz mww 0x400040BC 0 - mww 0x40004050 0x140 + mww 0x40004050 0x140 mww 0x40004040 0x4D mww 0x40004058 0x16250 @@ -37,7 +37,7 @@ proc phytec_lpc3250_init { } { sleep 1 busy mww 0x40004044 0x106 sleep 1 busy - mww 0x40004044 0x006 + mww 0x40004044 0x006 sleep 1 busy mww 0x40004048 0x2 @@ -49,7 +49,7 @@ proc phytec_lpc3250_init { } { mww 0x31080008 0 mww 0x40004068 0x1C000 mww 0x31080028 0x11 - + mww 0x31080400 0 mww 0x31080440 0 mww 0x31080460 0 @@ -66,7 +66,7 @@ proc phytec_lpc3250_init { } { mww 0x31080054 1 mww 0x31080058 1 mww 0x3108005C 0 - + mww 0x31080100 0x5680 mww 0x31080104 0x302 diff --git a/tcl/board/rsc-w910.cfg b/tcl/board/rsc-w910.cfg index cb1733b27..574de0c07 100644 --- a/tcl/board/rsc-w910.cfg +++ b/tcl/board/rsc-w910.cfg @@ -33,7 +33,7 @@ $_TARGETNAME configure -event reset-start {adapter speed 1000} $_TARGETNAME configure -event reset-init { # switch on PLL for 200MHz operation # running from 15MHz input clock - + mww 0xB0000200 0x00000030 ;# CLKEN mww 0xB0000204 0x00000f3c ;# CLKSEL mww 0xB0000208 0x05007000 ;# CLKDIV @@ -41,17 +41,17 @@ $_TARGETNAME configure -event reset-init { mww 0xB0000210 0x00002b63 ;# PLLCON1 mww 0xB000000C 0x08817fa6 ;# MFSEL sleep 10 - + # we are now running @ 200MHz # enable all openocd speed tweaks - + arm7_9 dcc_downloads enable arm7_9 fast_memory_access enable adapter speed 15000 - + # map nor flash to 0x20000000 # map sdram to 0x00000000 - + mww 0xb0001000 0x000530c1 ;# EBICON mww 0xb0001004 0x40030084 ;# ROMCON mww 0xb0001008 0x000010ee ;# SDCONF0 diff --git a/tcl/board/stm3210e_eval.cfg b/tcl/board/stm3210e_eval.cfg index 91807ce30..f30253c11 100644 --- a/tcl/board/stm3210e_eval.cfg +++ b/tcl/board/stm3210e_eval.cfg @@ -17,11 +17,11 @@ flash bank $_FLASHNAME cfi 0x64000000 0x01000000 2 2 $_TARGETNAME proc stm32_enable_fsmc {} { echo "Enabling FSMC Bank 1 (NOR/PSRAM Bank 2)" - + # enable gpio (defg) clocks for fsmc # RCC_APB2ENR mww 0x40021018 0x000001E0 - + # enable fsmc clock # RCC_AHBENR mww 0x40021014 0x00000114 @@ -31,29 +31,29 @@ proc stm32_enable_fsmc {} { mww 0x40011400 0x44BB44BB # GPIOD_CRH mww 0x40011404 0xBBBBBBBB - + # GPIOE_CRL mww 0x40011800 0xBBBBB444 # GPIOE_CRH mww 0x40011804 0xBBBBBBBB - + # GPIOF_CRL mww 0x40011C00 0x44BBBBBB # GPIOF_CRH mww 0x40011C04 0xBBBB4444 - + # GPIOG_CRL mww 0x40012000 0x44BBBBBB # GPIOG_CRH mww 0x40012004 0x444444B4 - + # setup fsmc timings # FSMC_BCR1 mww 0xA0000008 0x00001058 - + # FSMC_BTR1 mww 0xA000000C 0x10000502 - + # FSMC_BCR1 - enable fsmc mww 0xA0000008 0x00001059 } diff --git a/tcl/board/uptech_2410.cfg b/tcl/board/uptech_2410.cfg index 680cfd7d6..227cf42f6 100644 --- a/tcl/board/uptech_2410.cfg +++ b/tcl/board/uptech_2410.cfg @@ -11,28 +11,28 @@ proc init_pll_sdram { } { #echo "---------- Initializing PLL and SDRAM ---------" #watchdog timer disable mww phys 0x53000000 0x00000000 - + #disable all interrupts mww phys 0x4a000008 0xffffffff - + #disable all sub-interrupts mww phys 0x4a00001c 0x000007ff - + #clear all source pending bits mww phys 0x4a000000 0xffffffff - + #clear all sub-source pending bits mww phys 0x4a000018 0x000007ff - + #clear interrupt pending bit mww phys 0x4a000010 0xffffffff - + #PLL locktime counter mww phys 0x4c000000 0x00ffffff - + #Fin=12MHz Fout=202.8MHz #mww phys 0x4c000004 0x000a1031 - + #FCLK:HCLK:PCLK = 1:2:4 mww phys 0x4c000014 0x00000003 diff --git a/tcl/target/dsp56321.cfg b/tcl/target/dsp56321.cfg index 0ac0ce87c..78ecb3bd2 100644 --- a/tcl/target/dsp56321.cfg +++ b/tcl/target/dsp56321.cfg @@ -1,13 +1,13 @@ # Script for freescale DSP56321 # -if { [info exists CHIPNAME] } { +if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME dsp56321 } -if { [info exists ENDIAN] } { +if { [info exists ENDIAN] } { set _ENDIAN $ENDIAN } else { # this defaults to a big endian diff --git a/tcl/target/dsp568013.cfg b/tcl/target/dsp568013.cfg index 40fa3c2b0..67d44192e 100644 --- a/tcl/target/dsp568013.cfg +++ b/tcl/target/dsp568013.cfg @@ -1,12 +1,12 @@ # Script for freescale DSP568013 -if { [info exists CHIPNAME] } { +if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME dsp568013 } -if { [info exists ENDIAN] } { +if { [info exists ENDIAN] } { set _ENDIAN $ENDIAN } else { # this defaults to a big endian diff --git a/tcl/target/fm3.cfg b/tcl/target/fm3.cfg index 376320e83..544cff9d6 100644 --- a/tcl/target/fm3.cfg +++ b/tcl/target/fm3.cfg @@ -36,10 +36,10 @@ dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu set _TARGETNAME $_CHIPNAME.cpu target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -# MB9BF506 has 64kB of SRAM on its main system bus +# MB9BF506 has 64kB of SRAM on its main system bus $_TARGETNAME configure -work-area-phys 0x1FFF8000 -work-area-size 0x10000 -work-area-backup 0 -# MB9BF506 has 512kB internal FLASH +# MB9BF506 has 512kB internal FLASH set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME diff --git a/tcl/target/imx.cfg b/tcl/target/imx.cfg index 9eea53eef..ccfddb6f7 100644 --- a/tcl/target/imx.cfg +++ b/tcl/target/imx.cfg @@ -6,7 +6,7 @@ set TARGETNAME $_TARGETNAME # rewrite commands of the form below to arm11 mcr... # Data.Set c15:0x042f %long 0x40000015 proc setc15 {regs value} { - global TARGETNAME + global TARGETNAME echo [format "set p15 0x%04x, 0x%08x" $regs $value] diff --git a/tcl/target/ixp42x.cfg b/tcl/target/ixp42x.cfg index 3f86e357b..624fe29da 100644 --- a/tcl/target/ixp42x.cfg +++ b/tcl/target/ixp42x.cfg @@ -66,8 +66,8 @@ set IXP42x_SDRAM_256MB_32Mx16_2BANK 0x0015 # helper function to init SDRAM on IXP42x. # SDRAM_CFG: one of IXP42X_SDRAM_xxx -# REFRESH: refresh counter reload value (integer) -# CASLAT: 2 or 3 +# REFRESH: refresh counter reload value (integer) +# CASLAT: 2 or 3 proc ixp42x_init_sdram { SDRAM_CFG REFRESH CASLAT } { switch $CASLAT { diff --git a/tcl/target/lpc2103.cfg b/tcl/target/lpc2103.cfg index f55777f56..131b9ef89 100644 --- a/tcl/target/lpc2103.cfg +++ b/tcl/target/lpc2103.cfg @@ -15,7 +15,7 @@ proc setup_lpc2103 {core_freq_khz adapter_freq_khz} { proc init_targets {} { # default to core clocked with 12MHz crystal echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - + # setup_lpc2103 setup_lpc2103 12000 1500 } diff --git a/tcl/target/lpc2124.cfg b/tcl/target/lpc2124.cfg index 02517381a..ddbde22a5 100644 --- a/tcl/target/lpc2124.cfg +++ b/tcl/target/lpc2124.cfg @@ -15,7 +15,7 @@ proc setup_lpc2124 {core_freq_khz adapter_freq_khz} { proc init_targets {} { # default to core clocked with 12MHz crystal echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - + # setup_lpc2124 setup_lpc2124 12000 1500 } diff --git a/tcl/target/lpc2129.cfg b/tcl/target/lpc2129.cfg index 2c33cde31..a1c3fe7bb 100644 --- a/tcl/target/lpc2129.cfg +++ b/tcl/target/lpc2129.cfg @@ -15,7 +15,7 @@ proc setup_lpc2129 {core_freq_khz adapter_freq_khz} { proc init_targets {} { # default to core clocked with 12MHz crystal echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - + # setup_lpc2129 setup_lpc2129 12000 1500 } diff --git a/tcl/target/lpc2148.cfg b/tcl/target/lpc2148.cfg index f3a2011a8..503a68264 100644 --- a/tcl/target/lpc2148.cfg +++ b/tcl/target/lpc2148.cfg @@ -15,7 +15,7 @@ proc setup_lpc2148 {core_freq_khz adapter_freq_khz} { proc init_targets {} { # default to core clocked with 12MHz crystal echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - + # setup_lpc2148 setup_lpc2148 12000 1500 } diff --git a/tcl/target/lpc2294.cfg b/tcl/target/lpc2294.cfg index 83d595deb..1320cda3e 100644 --- a/tcl/target/lpc2294.cfg +++ b/tcl/target/lpc2294.cfg @@ -9,7 +9,7 @@ source [find target/lpc2xxx.cfg] proc setup_lpc2294 {core_freq_khz adapter_freq_khz} { # 256kB flash and 16kB SRAM # setup_lpc2xxx - + # !! TAPID unknown !! setup_lpc2xxx lpc2294 0xffffffff 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz } @@ -17,7 +17,7 @@ proc setup_lpc2294 {core_freq_khz adapter_freq_khz} { proc init_targets {} { # default to core clocked with 12MHz crystal echo "Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different." - + # setup_lpc2294 setup_lpc2294 12000 1500 } diff --git a/tcl/target/lpc2378.cfg b/tcl/target/lpc2378.cfg index 0b66b8255..235456a07 100644 --- a/tcl/target/lpc2378.cfg +++ b/tcl/target/lpc2378.cfg @@ -15,7 +15,7 @@ proc setup_lpc2378 {core_freq_khz adapter_freq_khz} { proc init_targets {} { # default to core clocked with 4MHz internal oscillator echo "Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different." - + # setup_lpc2378 setup_lpc2378 4000 500 } diff --git a/tcl/target/lpc2460.cfg b/tcl/target/lpc2460.cfg index 69fdc4aaf..c229f6dd6 100644 --- a/tcl/target/lpc2460.cfg +++ b/tcl/target/lpc2460.cfg @@ -15,7 +15,7 @@ proc setup_lpc2460 {core_freq_khz adapter_freq_khz} { proc init_targets {} { # default to core clocked with 4MHz internal oscillator echo "Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different." - + # setup_lpc2460 setup_lpc2460 4000 500 } diff --git a/tcl/target/lpc2478.cfg b/tcl/target/lpc2478.cfg index 48e5bdf3f..36b5c4693 100644 --- a/tcl/target/lpc2478.cfg +++ b/tcl/target/lpc2478.cfg @@ -15,7 +15,7 @@ proc setup_lpc2478 {core_freq_khz adapter_freq_khz} { proc init_targets {} { # default to core clocked with 4MHz internal oscillator echo "Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different." - + # setup_lpc2478 setup_lpc2478 4000 500 } diff --git a/tcl/target/lpc2xxx.cfg b/tcl/target/lpc2xxx.cfg index 4c3394c95..f947c1b05 100644 --- a/tcl/target/lpc2xxx.cfg +++ b/tcl/target/lpc2xxx.cfg @@ -40,5 +40,5 @@ proc setup_lpc2xxx {chip_name cputapids flash_size flash_variant workarea_size c proc init_targets {} { # FIX!!! read out CPUTAPID here and choose right setup. In addition to the # CPUTAPID some querying of the target would be required. - return -error "This is a generic LPC2xxx configuration file, use a specific target file." + return -error "This is a generic LPC2xxx configuration file, use a specific target file." } diff --git a/tcl/target/lpc3131.cfg b/tcl/target/lpc3131.cfg index d6f2cdbda..89bbf0265 100644 --- a/tcl/target/lpc3131.cfg +++ b/tcl/target/lpc3131.cfg @@ -56,7 +56,7 @@ adapter srst delay 1000 jtag_ntrst_delay 0 set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME +target create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME $_TARGETNAME invoke-event halted diff --git a/tcl/target/u8500.cfg b/tcl/target/u8500.cfg index baef9c81f..36e0db71d 100644 --- a/tcl/target/u8500.cfg +++ b/tcl/target/u8500.cfg @@ -1,6 +1,6 @@ # Copyright (C) ST-Ericsson SA 2011 # Author : michel.jaouen@stericsson.com -# U8500 target +# U8500 target proc mmu_off {} { set cp [arm mrc 15 0 1 0 0] @@ -31,7 +31,7 @@ proc ocd_gdb_restart {target_id} { proc smp_reg {} { global _TARGETNAME_1 global _TARGETNAME_2 - targets $_TARGETNAME_1 + targets $_TARGETNAME_1 echo "$_TARGETNAME_1" set pc1 [reg pc] set stck1 [reg sp_svc] @@ -68,7 +68,7 @@ proc pwrsts { } { 8 { echo "A9 100% DVFS" } - c { + c { echo "A9 50% DVFS" } } @@ -144,7 +144,7 @@ tcl_port 5555 telnet_port 4444 gdb_port 3333 -if { [info exists CHIPNAME] } { +if { [info exists CHIPNAME] } { global _CHIPNAME set _CHIPNAME $CHIPNAME } else { @@ -194,12 +194,12 @@ set _TARGETNAME_1 $TARGETNAME_1 if { [info exists DAP_DBG1] } { set _DAP_DBG1 $DAP_DBG1 } else { - set _DAP_DBG1 0x801A8000 + set _DAP_DBG1 0x801A8000 } if { [info exists DAP_DBG2] } { set _DAP_DBG2 $DAP_DBG2 } else { - set _DAP_DBG2 0x801AA000 + set _DAP_DBG2 0x801AA000 } dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu @@ -226,7 +226,7 @@ global _SMP set _SMP $SMP } global SMP -if { $_SMP == 1} { +if { $_SMP == 1} { target smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1 } @@ -264,7 +264,7 @@ proc att { } { } else { echo "target secured" } - + } @@ -310,10 +310,10 @@ if {![info exists MAXSPEED]} { global _MAXSPEED set _MAXSPEED 15000 } else { -global _MAXSPEED +global _MAXSPEED set _MAXSPEED $MAXSPEED } -global _MAXSPEED +global _MAXSPEED adapter speed $_MAXSPEED From 9b29cb58acbd14ed831d68fce4d6e6a1728f8caf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 00:03:03 +0200 Subject: [PATCH 295/354] coding style: remove useless break after a goto or return In a switch/case statement, a break placed after a goto or return is never executed. The script checkpatch available in Linux kernel v5.1 issues a warning for such unused break statements. In the process of reviewing the new checkpatch for its inclusion in OpenOCD, let's get rid of these warnings. The script checkpatch is unable to fixup automatically this case. Thanks to having "break" command using a single code line, this patch has been generated using the script below: find src/ -type f -exec ./tools/scripts/checkpatch.pl -q \ --types UNNECESSARY_BREAK -f {} \; \ | sed -n '/^#/{s/^.*FILE: //;s/:$//;s/:/ /;p}' \ | awk 'function P() {print "sed -i '\''"b"'\'' "a}; { if ($1!=a) { if (a) {P()}; a=$1; b=$2"{d}"; } else { b=b";"$2"{d}" } }; END {P()}' Change-Id: I56ca098faa5fe8d1e3f712dc0a029a3f10559d99 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5617 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/flash/nand/mx3.c | 2 -- src/flash/nand/mxc.c | 2 -- src/flash/nor/aducm360.c | 2 -- src/flash/nor/at91sam3.c | 4 ---- src/flash/nor/at91sam4.c | 4 ---- src/flash/nor/atsamv.c | 3 --- src/flash/nor/cfi.c | 12 ------------ src/flash/nor/psoc6.c | 5 ----- src/flash/nor/xcf.c | 1 - src/jtag/drivers/stlink_usb.c | 1 - src/jtag/drivers/ulink.c | 18 ------------------ src/svf/svf.c | 2 -- src/target/arm_disassembler.c | 1 - src/target/arm_dpm.c | 2 -- src/target/armv4_5.c | 3 --- src/target/avr32_ap7k.c | 2 -- src/target/riscv/riscv-013.c | 2 -- src/transport/transport.c | 2 -- 18 files changed, 68 deletions(-) diff --git a/src/flash/nand/mx3.c b/src/flash/nand/mx3.c index 5fdc92305..da141b742 100644 --- a/src/flash/nand/mx3.c +++ b/src/flash/nand/mx3.c @@ -685,7 +685,6 @@ static int do_data_output(struct nand_device *nand) case 2 << 2: LOG_DEBUG("main area readed with more than 1 (incorrectable) error"); return ERROR_NAND_OPERATION_FAILED; - break; } switch (ecc_status & 0x0003) { case 1: @@ -694,7 +693,6 @@ static int do_data_output(struct nand_device *nand) case 2: LOG_DEBUG("main area readed with more than 1 (incorrectable) error"); return ERROR_NAND_OPERATION_FAILED; - break; } } break; diff --git a/src/flash/nand/mxc.c b/src/flash/nand/mxc.c index b54115731..ee093c056 100644 --- a/src/flash/nand/mxc.c +++ b/src/flash/nand/mxc.c @@ -874,7 +874,6 @@ int ecc_status_v1(struct nand_device *nand) case 2 << 2: LOG_INFO("main area read with more than 1 (incorrectable) error"); return ERROR_NAND_OPERATION_FAILED; - break; } switch (ecc_status & 0x0003) { case 1: @@ -883,7 +882,6 @@ int ecc_status_v1(struct nand_device *nand) case 2: LOG_INFO("main area read with more than 1 (incorrectable) error"); return ERROR_NAND_OPERATION_FAILED; - break; } return ERROR_OK; } diff --git a/src/flash/nor/aducm360.c b/src/flash/nor/aducm360.c index f468c89a5..7c5596d48 100644 --- a/src/flash/nor/aducm360.c +++ b/src/flash/nor/aducm360.c @@ -434,10 +434,8 @@ static int aducm360_write_block(struct flash_bank *bank, switch (choice) { case 0: return aducm360_write_block_sync(bank, buffer, offset, count); - break; case 1: return aducm360_write_block_async(bank, buffer, offset, count); - break; default: LOG_ERROR("aducm360_write_block was cancelled (no writing method was chosen)!"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c index af0b50b49..b51e0972a 100644 --- a/src/flash/nor/at91sam3.c +++ b/src/flash/nor/at91sam3.c @@ -3068,7 +3068,6 @@ FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command) ((unsigned int)(FLASH_BANK1_BASE_256K_AX)), ((unsigned int)(FLASH_BANK1_BASE_512K_AX))); return ERROR_FAIL; - break; /* at91sam3s and at91sam3n series only has bank 0*/ /* at91sam3u and at91sam3ax series has the same address for bank 0*/ @@ -3621,10 +3620,8 @@ COMMAND_HANDLER(sam3_handle_gpnvm_command) switch (CMD_ARGC) { default: return ERROR_COMMAND_SYNTAX_ERROR; - break; case 0: goto showall; - break; case 1: who = -1; break; @@ -3708,7 +3705,6 @@ COMMAND_HANDLER(sam3_handle_slowclk_command) /* error */ command_print(CMD, "Too many parameters"); return ERROR_COMMAND_SYNTAX_ERROR; - break; } command_print(CMD, "Slowclk freq: %d.%03dkhz", (int)(pChip->cfg.slow_freq / 1000), diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c index 621754c90..135fc99bf 100644 --- a/src/flash/nor/at91sam4.c +++ b/src/flash/nor/at91sam4.c @@ -2482,7 +2482,6 @@ FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command) ((unsigned int)(bank->base)), ((unsigned int)(FLASH_BANK_BASE_S))); return ERROR_FAIL; - break; /* at91sam4s series only has bank 0*/ /* at91sam4sd series has the same address for bank 0 (FLASH_BANK0_BASE_SD)*/ @@ -3101,10 +3100,8 @@ COMMAND_HANDLER(sam4_handle_gpnvm_command) switch (CMD_ARGC) { default: return ERROR_COMMAND_SYNTAX_ERROR; - break; case 0: goto showall; - break; case 1: who = -1; break; @@ -3188,7 +3185,6 @@ COMMAND_HANDLER(sam4_handle_slowclk_command) /* error */ command_print(CMD, "Too many parameters"); return ERROR_COMMAND_SYNTAX_ERROR; - break; } command_print(CMD, "Slowclk freq: %d.%03dkhz", (int)(pChip->cfg.slow_freq / 1000), diff --git a/src/flash/nor/atsamv.c b/src/flash/nor/atsamv.c index d6f1a0a48..9a53369a7 100644 --- a/src/flash/nor/atsamv.c +++ b/src/flash/nor/atsamv.c @@ -375,7 +375,6 @@ static int samv_probe(struct flash_bank *bank) default: LOG_ERROR("unrecognized flash size code: %d", nvm_size_code); return ERROR_FAIL; - break; } struct samv_flash_bank *samv_info = bank->driver_priv; @@ -645,7 +644,6 @@ COMMAND_HANDLER(samv_handle_gpnvm_command) switch (CMD_ARGC) { case 0: goto showall; - break; case 1: who = -1; break; @@ -660,7 +658,6 @@ COMMAND_HANDLER(samv_handle_gpnvm_command) break; default: return ERROR_COMMAND_SYNTAX_ERROR; - break; } uint32_t v; diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 80a0a33ee..73884b786 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -989,10 +989,8 @@ int cfi_erase(struct flash_bank *bank, int first, int last) case 1: case 3: return cfi_intel_erase(bank, first, last); - break; case 2: return cfi_spansion_erase(bank, first, last); - break; default: LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); break; @@ -1128,7 +1126,6 @@ int cfi_protect(struct flash_bank *bank, int set, int first, int last) case 1: case 3: return cfi_intel_protect(bank, set, first, last); - break; default: LOG_WARNING("protect: cfi primary command set %i unsupported", cfi_info->pri_id); return ERROR_OK; @@ -1144,13 +1141,10 @@ static uint32_t cfi_command_val(struct flash_bank *bank, uint8_t cmd) switch (bank->bus_width) { case 1: return buf[0]; - break; case 2: return target_buffer_get_u16(target, buf); - break; case 4: return target_buffer_get_u32(target, buf); - break; default: LOG_ERROR("Unsupported bank buswidth %d, can't do block memory writes", bank->bus_width); @@ -2222,10 +2216,8 @@ int cfi_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address) case 1: case 3: return cfi_intel_write_word(bank, word, address); - break; case 2: return cfi_spansion_write_word(bank, word, address); - break; default: LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); break; @@ -2249,10 +2241,8 @@ static int cfi_write_words(struct flash_bank *bank, const uint8_t *word, case 1: case 3: return cfi_intel_write_words(bank, word, wordcount, address); - break; case 2: return cfi_spansion_write_words(bank, word, wordcount, address); - break; default: LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); break; @@ -2998,10 +2988,8 @@ int cfi_protect_check(struct flash_bank *bank) case 1: case 3: return cfi_intel_protect_check(bank); - break; case 2: return cfi_spansion_protect_check(bank); - break; default: LOG_ERROR("cfi primary command set %i unsupported", cfi_info->pri_id); break; diff --git a/src/flash/nor/psoc6.c b/src/flash/nor/psoc6.c index 3cdfcc424..a8f8d3f08 100644 --- a/src/flash/nor/psoc6.c +++ b/src/flash/nor/psoc6.c @@ -481,20 +481,15 @@ static const char *protection_to_str(uint8_t protection) switch (protection) { case PROTECTION_VIRGIN: return "VIRGIN"; - break; case PROTECTION_NORMAL: return "NORMAL"; - break; case PROTECTION_SECURE: return "SECURE"; - break; case PROTECTION_DEAD: return "DEAD"; - break; case PROTECTION_UNKNOWN: default: return "UNKNOWN"; - break; } } diff --git a/src/flash/nor/xcf.c b/src/flash/nor/xcf.c index a0c35c5e5..ba35c2c10 100644 --- a/src/flash/nor/xcf.c +++ b/src/flash/nor/xcf.c @@ -625,7 +625,6 @@ static int xcf_probe(struct flash_bank *bank) default: LOG_ERROR("Unknown flash device ID 0x%X", id); return ERROR_FAIL; - break; } bank->sectors = malloc(bank->num_sectors * sizeof(struct flash_sector)); diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index a905576c8..14bac2a2f 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -2677,7 +2677,6 @@ static int stlink_speed(void *handle, int khz, bool query) switch (h->transport) { case HL_TRANSPORT_SWIM: return stlink_speed_swim(handle, khz, query); - break; case HL_TRANSPORT_SWD: if (h->version.jtag_api == STLINK_JTAG_API_V3) return stlink_speed_v3(handle, false, khz, query); diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c index c6683abda..242c04fe3 100644 --- a/src/jtag/drivers/ulink.c +++ b/src/jtag/drivers/ulink.c @@ -765,58 +765,40 @@ static const char *ulink_cmd_id_string(uint8_t id) switch (id) { case CMD_SCAN_IN: return "CMD_SCAN_IN"; - break; case CMD_SLOW_SCAN_IN: return "CMD_SLOW_SCAN_IN"; - break; case CMD_SCAN_OUT: return "CMD_SCAN_OUT"; - break; case CMD_SLOW_SCAN_OUT: return "CMD_SLOW_SCAN_OUT"; - break; case CMD_SCAN_IO: return "CMD_SCAN_IO"; - break; case CMD_SLOW_SCAN_IO: return "CMD_SLOW_SCAN_IO"; - break; case CMD_CLOCK_TMS: return "CMD_CLOCK_TMS"; - break; case CMD_SLOW_CLOCK_TMS: return "CMD_SLOW_CLOCK_TMS"; - break; case CMD_CLOCK_TCK: return "CMD_CLOCK_TCK"; - break; case CMD_SLOW_CLOCK_TCK: return "CMD_SLOW_CLOCK_TCK"; - break; case CMD_SLEEP_US: return "CMD_SLEEP_US"; - break; case CMD_SLEEP_MS: return "CMD_SLEEP_MS"; - break; case CMD_GET_SIGNALS: return "CMD_GET_SIGNALS"; - break; case CMD_SET_SIGNALS: return "CMD_SET_SIGNALS"; - break; case CMD_CONFIGURE_TCK_FREQ: return "CMD_CONFIGURE_TCK_FREQ"; - break; case CMD_SET_LEDS: return "CMD_SET_LEDS"; - break; case CMD_TEST: return "CMD_TEST"; - break; default: return "CMD_UNKNOWN"; - break; } } diff --git a/src/svf/svf.c b/src/svf/svf.c index 5d87c8944..54fc7d139 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -1310,7 +1310,6 @@ XXR_common: case PIOMAP: LOG_ERROR("PIO and PIOMAP are not supported"); return ERROR_FAIL; - break; case RUNTEST: /* RUNTEST [run_state] run_count run_clk [min_time SEC [MAXIMUM max_time * SEC]] [ENDSTATE end_state] */ @@ -1532,7 +1531,6 @@ XXR_common: default: LOG_ERROR("invalid svf command: %s", argus[0]); return ERROR_FAIL; - break; } if (!svf_quiet) { diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 8eb819446..04c392296 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -2309,7 +2309,6 @@ static int evaluate_data_proc_thumb(uint16_t opcode, address, opcode); } return ERROR_OK; - break; } } else { switch (op) { diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index f5dd22d8b..a01339c1f 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -212,7 +212,6 @@ int arm_dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) break; case ARM_VFP_V3_D0 ... ARM_VFP_V3_D31: return dpm_read_reg_u64(dpm, r, regnum); - break; case ARM_VFP_V3_FPSCR: /* "VMRS r0, FPSCR"; then return via DCC */ retval = dpm->instr_read_data_r0(dpm, @@ -294,7 +293,6 @@ static int dpm_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum) break; case ARM_VFP_V3_D0 ... ARM_VFP_V3_D31: return dpm_write_reg_u64(dpm, r, regnum); - break; case ARM_VFP_V3_FPSCR: /* move to r0 from DCC, then "VMSR FPSCR, r0" */ retval = dpm->instr_write_data_r0(dpm, diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index a0983cd54..b4581d5f1 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -1223,7 +1223,6 @@ int arm_get_gdb_reg_list(struct target *target, (*reg_list)[25] = arm->cpsr; return ERROR_OK; - break; case REG_CLASS_ALL: switch (arm->core_type) { @@ -1273,12 +1272,10 @@ int arm_get_gdb_reg_list(struct target *target, } return ERROR_OK; - break; default: LOG_ERROR("not a valid register class type in query."); return ERROR_FAIL; - break; } } diff --git a/src/target/avr32_ap7k.c b/src/target/avr32_ap7k.c index cf08e3ab9..622105913 100644 --- a/src/target/avr32_ap7k.c +++ b/src/target/avr32_ap7k.c @@ -464,7 +464,6 @@ static int avr32_ap7k_read_memory(struct target *target, target_addr_t address, break; case 1: return avr32_jtag_read_memory8(&ap7k->jtag, address, count, buffer); - break; default: break; } @@ -505,7 +504,6 @@ static int avr32_ap7k_write_memory(struct target *target, target_addr_t address, break; case 1: return avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer); - break; default: break; } diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 8307b0224..e30294114 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -666,10 +666,8 @@ uint32_t abstract_register_size(unsigned width) return set_field(0, AC_ACCESS_REGISTER_SIZE, 2); case 64: return set_field(0, AC_ACCESS_REGISTER_SIZE, 3); - break; case 128: return set_field(0, AC_ACCESS_REGISTER_SIZE, 4); - break; default: LOG_ERROR("Unsupported register width: %d", width); return 0; diff --git a/src/transport/transport.c b/src/transport/transport.c index 77db9e210..010ea7c44 100644 --- a/src/transport/transport.c +++ b/src/transport/transport.c @@ -290,7 +290,6 @@ static int jim_transport_select(Jim_Interp *interp, int argc, Jim_Obj * const *a } Jim_SetResultString(interp, session->name, -1); return JIM_OK; - break; case 2: /* assign */ if (session) { if (!strcmp(session->name, argv[1]->bytes)) { @@ -327,7 +326,6 @@ static int jim_transport_select(Jim_Interp *interp, int argc, Jim_Obj * const *a LOG_ERROR("Debug adapter doesn't support '%s' transport", argv[1]->bytes); return JIM_ERR; - break; default: Jim_WrongNumArgs(interp, 1, argv, "[too many parameters]"); return JIM_ERR; From e66bb9d3121eef35c312997aacb401847249a5cb Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 00:35:52 +0200 Subject: [PATCH 296/354] coding style: add parenthesis around the argument of sizeof The script checkpatch available in new Linux kernel offers an experimental feature for automatically fix the code in place. While still experimental, the feature works quite well for simple fixes, like parenthesis. This patch has been created automatically with the script under review for inclusion in OpenOCD, using the command: find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types SIZEOF_PARENTHESIS --fix-inplace -f {} \; Change-Id: I8adb325bdb0e13211f8bae8b4770ec1979c176bf Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5618 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/flash/nand/davinci.c | 2 +- src/jtag/aice/aice_transport.c | 4 ++-- src/jtag/core.c | 2 +- src/jtag/drivers/amt_jtagaccel.c | 2 +- src/jtag/drivers/gw16012.c | 2 +- src/jtag/drivers/kitprog.c | 6 +++--- src/jtag/drivers/parport.c | 2 +- src/jtag/tcl.c | 4 ++-- src/target/arm11.c | 2 +- src/target/arm11_dbgtap.c | 2 +- src/target/arm_disassembler.c | 2 +- src/target/arm_dpm.c | 4 ++-- src/target/armv8_dpm.c | 4 ++-- src/target/cortex_m.c | 6 +++--- src/target/xscale.c | 20 ++++++++++---------- 15 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/flash/nand/davinci.c b/src/flash/nand/davinci.c index 17e6f680d..167b40150 100644 --- a/src/flash/nand/davinci.c +++ b/src/flash/nand/davinci.c @@ -730,7 +730,7 @@ NAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command) goto fail; } - info = calloc(1, sizeof *info); + info = calloc(1, sizeof(*info)); if (info == NULL) goto fail; diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c index d0f7a49c0..ea710ad25 100644 --- a/src/jtag/aice/aice_transport.c +++ b/src/jtag/aice/aice_transport.c @@ -174,7 +174,7 @@ COMMAND_HANDLER(handle_scan_chain_command) while (tap) { uint32_t expected, expected_mask, ii; - snprintf(expected_id, sizeof expected_id, "0x%08x", + snprintf(expected_id, sizeof(expected_id), "0x%08x", (unsigned)((tap->expected_ids_cnt > 0) ? tap->expected_ids[0] : 0)); @@ -196,7 +196,7 @@ COMMAND_HANDLER(handle_scan_chain_command) (unsigned int)(expected_mask)); for (ii = 1; ii < tap->expected_ids_cnt; ii++) { - snprintf(expected_id, sizeof expected_id, "0x%08x", + snprintf(expected_id, sizeof(expected_id), "0x%08x", (unsigned) tap->expected_ids[ii]); if (tap->ignore_version) expected_id[2] = '*'; diff --git a/src/jtag/core.c b/src/jtag/core.c index 2d0c84205..f12ab5924 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1269,7 +1269,7 @@ static int jtag_examine_chain(void) * REVISIT create a jtag_alloc(chip, tap) routine, and * share it with jim_newtap_cmd(). */ - tap = calloc(1, sizeof *tap); + tap = calloc(1, sizeof(*tap)); if (!tap) { retval = ERROR_FAIL; goto out; diff --git a/src/jtag/drivers/amt_jtagaccel.c b/src/jtag/drivers/amt_jtagaccel.c index db106bb05..f5918a055 100644 --- a/src/jtag/drivers/amt_jtagaccel.c +++ b/src/jtag/drivers/amt_jtagaccel.c @@ -393,7 +393,7 @@ int amt_jtagaccel_get_giveio_access(void) HANDLE h; OSVERSIONINFO version; - version.dwOSVersionInfoSize = sizeof version; + version.dwOSVersionInfoSize = sizeof(version); if (!GetVersionEx(&version)) { errno = EINVAL; return -1; diff --git a/src/jtag/drivers/gw16012.c b/src/jtag/drivers/gw16012.c index 2e8dad896..d1699ef01 100644 --- a/src/jtag/drivers/gw16012.c +++ b/src/jtag/drivers/gw16012.c @@ -350,7 +350,7 @@ static int gw16012_get_giveio_access(void) HANDLE h; OSVERSIONINFO version; - version.dwOSVersionInfoSize = sizeof version; + version.dwOSVersionInfoSize = sizeof(version); if (!GetVersionEx(&version)) { errno = EINVAL; return -1; diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index 28ed7ac61..efb8da2cd 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -358,7 +358,7 @@ static int kitprog_get_version(void) unsigned char command[3] = {HID_TYPE_START | HID_TYPE_WRITE, 0x00, HID_COMMAND_VERSION}; unsigned char data[64]; - ret = kitprog_hid_command(command, sizeof command, data, sizeof data); + ret = kitprog_hid_command(command, sizeof(command), data, sizeof(data)); if (ret != ERROR_OK) return ret; @@ -376,7 +376,7 @@ static int kitprog_get_millivolts(void) unsigned char command[3] = {HID_TYPE_START | HID_TYPE_READ, 0x00, HID_COMMAND_POWER}; unsigned char data[64]; - ret = kitprog_hid_command(command, sizeof command, data, sizeof data); + ret = kitprog_hid_command(command, sizeof(command), data, sizeof(data)); if (ret != ERROR_OK) return ret; @@ -603,7 +603,7 @@ static int kitprog_generic_acquire(void) * will take the Cortex-M3 out of reset and enable debugging. */ for (int i = 0; i < 2; i++) { - for (uint8_t j = 0; j < sizeof devices && acquire_count == i; j++) { + for (uint8_t j = 0; j < sizeof(devices) && acquire_count == i; j++) { retval = kitprog_acquire_psoc(devices[j], ACQUIRE_MODE_RESET, 3); if (retval != ERROR_OK) { LOG_DEBUG("Aquisition function failed for device 0x%02x.", devices[j]); diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c index 6d15203ae..b3abd1205 100644 --- a/src/jtag/drivers/parport.c +++ b/src/jtag/drivers/parport.c @@ -237,7 +237,7 @@ static int parport_get_giveio_access(void) HANDLE h; OSVERSIONINFO version; - version.dwOSVersionInfoSize = sizeof version; + version.dwOSVersionInfoSize = sizeof(version); if (!GetVersionEx(&version)) { errno = EINVAL; return -1; diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 734b9c1cb..f52cbd606 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -965,7 +965,7 @@ COMMAND_HANDLER(handle_scan_chain_command) while (tap) { uint32_t expected, expected_mask, ii; - snprintf(expected_id, sizeof expected_id, "0x%08x", + snprintf(expected_id, sizeof(expected_id), "0x%08x", (unsigned)((tap->expected_ids_cnt > 0) ? tap->expected_ids[0] : 0)); @@ -987,7 +987,7 @@ COMMAND_HANDLER(handle_scan_chain_command) (unsigned int)(expected_mask)); for (ii = 1; ii < tap->expected_ids_cnt; ii++) { - snprintf(expected_id, sizeof expected_id, "0x%08x", + snprintf(expected_id, sizeof(expected_id), "0x%08x", (unsigned) tap->expected_ids[ii]); if (tap->ignore_version) expected_id[2] = '*'; diff --git a/src/target/arm11.c b/src/target/arm11.c index 51f2a337a..10a1d6de5 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -1105,7 +1105,7 @@ static int arm11_target_create(struct target *target, Jim_Interp *interp) return ERROR_COMMAND_SYNTAX_ERROR; } - arm11 = calloc(1, sizeof *arm11); + arm11 = calloc(1, sizeof(*arm11)); if (!arm11) return ERROR_FAIL; diff --git a/src/target/arm11_dbgtap.c b/src/target/arm11_dbgtap.c index 2232b3ef6..a758db58f 100644 --- a/src/target/arm11_dbgtap.c +++ b/src/target/arm11_dbgtap.c @@ -1183,7 +1183,7 @@ int arm11_dpm_init(struct arm11_common *arm11, uint32_t didr) /* alloc enough to enable all breakpoints and watchpoints at once */ arm11->bpwp_actions = calloc(2 * (dpm->nbp + dpm->nwp), - sizeof *arm11->bpwp_actions); + sizeof(*arm11->bpwp_actions)); if (!arm11->bpwp_actions) return ERROR_FAIL; diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 04c392296..55aaddd0a 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -2672,7 +2672,7 @@ static int evaluate_load_store_multiple_thumb(uint16_t opcode, instruction->type = ARM_STM; mnemonic = "STM"; } - snprintf(ptr_name, sizeof ptr_name, "r%i%s, ", Rn, wback); + snprintf(ptr_name, sizeof(ptr_name), "r%i%s, ", Rn, wback); } else {/* push/pop */ Rn = 13;/* SP */ if (L) { diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index a01339c1f..495d63ec2 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -1096,8 +1096,8 @@ int arm_dpm_setup(struct arm_dpm *dpm) dpm->nbp = 1 + ((dpm->didr >> 24) & 0xf); dpm->nwp = 1 + ((dpm->didr >> 28) & 0xf); - dpm->dbp = calloc(dpm->nbp, sizeof *dpm->dbp); - dpm->dwp = calloc(dpm->nwp, sizeof *dpm->dwp); + dpm->dbp = calloc(dpm->nbp, sizeof(*dpm->dbp)); + dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp)); if (!dpm->dbp || !dpm->dwp) { free(dpm->dbp); diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c index 5be52726c..a3edb7f47 100644 --- a/src/target/armv8_dpm.c +++ b/src/target/armv8_dpm.c @@ -1471,10 +1471,10 @@ int armv8_dpm_setup(struct arm_dpm *dpm) /* FIXME add vector catch support */ dpm->nbp = 1 + ((dpm->didr >> 12) & 0xf); - dpm->dbp = calloc(dpm->nbp, sizeof *dpm->dbp); + dpm->dbp = calloc(dpm->nbp, sizeof(*dpm->dbp)); dpm->nwp = 1 + ((dpm->didr >> 20) & 0xf); - dpm->dwp = calloc(dpm->nwp, sizeof *dpm->dwp); + dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp)); if (!dpm->dbp || !dpm->dwp) { free(dpm->dbp); diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index af245dfc0..27febd3d7 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -1980,7 +1980,7 @@ static void cortex_m_dwt_addreg(struct target *t, struct reg *r, const struct dw { struct dwt_reg_state *state; - state = calloc(1, sizeof *state); + state = calloc(1, sizeof(*state)); if (!state) return; state->addr = d->addr; @@ -2021,7 +2021,7 @@ fail0: return; } - cache = calloc(1, sizeof *cache); + cache = calloc(1, sizeof(*cache)); if (!cache) { fail1: free(cm->dwt_comparator_list); @@ -2029,7 +2029,7 @@ fail1: } cache->name = "Cortex-M DWT registers"; cache->num_regs = 2 + cm->dwt_num_comp * 3; - cache->reg_list = calloc(cache->num_regs, sizeof *cache->reg_list); + cache->reg_list = calloc(cache->num_regs, sizeof(*cache->reg_list)); if (!cache->reg_list) { free(cache); goto fail1; diff --git a/src/target/xscale.c b/src/target/xscale.c index f879a9cc9..edab4f9fc 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -156,7 +156,7 @@ static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_s struct scan_field field; uint8_t scratch[4] = { 0 }; - memset(&field, 0, sizeof field); + memset(&field, 0, sizeof(field)); field.num_bits = tap->ir_length; field.out_value = scratch; buf_set_u32(scratch, 0, field.num_bits, new_instr); @@ -186,7 +186,7 @@ static int xscale_read_dcsr(struct target *target) buf_set_u32(&field0, 1, 1, xscale->hold_rst); buf_set_u32(&field0, 2, 1, xscale->external_debug_break); - memset(&fields, 0, sizeof fields); + memset(&fields, 0, sizeof(fields)); fields[0].num_bits = 3; fields[0].out_value = &field0; @@ -259,7 +259,7 @@ static int xscale_receive(struct target *target, uint32_t *buffer, int num_words path[1] = TAP_DRCAPTURE; path[2] = TAP_DRSHIFT; - memset(&fields, 0, sizeof fields); + memset(&fields, 0, sizeof(fields)); fields[0].num_bits = 3; uint8_t tmp; @@ -367,7 +367,7 @@ static int xscale_read_tx(struct target *target, int consume) noconsume_path[4] = TAP_DREXIT2; noconsume_path[5] = TAP_DRSHIFT; - memset(&fields, 0, sizeof fields); + memset(&fields, 0, sizeof(fields)); fields[0].num_bits = 3; fields[0].in_value = &field0_in; @@ -442,7 +442,7 @@ static int xscale_write_rx(struct target *target) XSCALE_DBGRX << xscale->xscale_variant, TAP_IDLE); - memset(&fields, 0, sizeof fields); + memset(&fields, 0, sizeof(fields)); fields[0].num_bits = 3; fields[0].out_value = &field0_out; @@ -598,7 +598,7 @@ static int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_br buf_set_u32(&field0, 1, 1, xscale->hold_rst); buf_set_u32(&field0, 2, 1, xscale->external_debug_break); - memset(&fields, 0, sizeof fields); + memset(&fields, 0, sizeof(fields)); fields[0].num_bits = 3; fields[0].out_value = &field0; @@ -666,7 +666,7 @@ static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8] /* virtual address of desired cache line */ buf_set_u32(packet, 0, 27, va >> 5); - memset(&fields, 0, sizeof fields); + memset(&fields, 0, sizeof(fields)); fields[0].num_bits = 6; fields[0].out_value = &cmd; @@ -713,7 +713,7 @@ static int xscale_invalidate_ic_line(struct target *target, uint32_t va) /* virtual address of desired cache line */ buf_set_u32(packet, 0, 27, va >> 5); - memset(&fields, 0, sizeof fields); + memset(&fields, 0, sizeof(fields)); fields[0].num_bits = 6; fields[0].out_value = &cmd; @@ -1551,7 +1551,7 @@ static int xscale_deassert_reset(struct target *target) * coprocessors, trace data, etc. */ address = xscale->handler_address; - for (unsigned binary_size = sizeof xscale_debug_handler; + for (unsigned binary_size = sizeof(xscale_debug_handler); binary_size > 0; binary_size -= buf_cnt, buffer += buf_cnt) { uint32_t cache_line[8]; @@ -3004,7 +3004,7 @@ static int xscale_target_create(struct target *target, Jim_Interp *interp) { struct xscale_common *xscale; - if (sizeof xscale_debug_handler > 0x800) { + if (sizeof(xscale_debug_handler) > 0x800) { LOG_ERROR("debug_handler.bin: larger than 2kb"); return ERROR_FAIL; } From 4f459660a9dab3877f6f27127e565dd2b49b4ec7 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 01:03:52 +0200 Subject: [PATCH 297/354] coding style: avoid unnecessary line continuations Line continuation, adding a backslash as last char of the line, is requested in multi-line macro definition, but is not necessary in the rest of C code. Remove it where present. Identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types LINE_CONTINUATIONS -f {} \; Change-Id: Id0c69e93456731717a7b290b16580e9f8ae741bc Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5619 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/flash/nor/cfi.c | 2 +- src/flash/nor/fespi.c | 2 +- src/flash/nor/kinetis_ke.c | 2 +- src/flash/nor/lpcspifi.c | 16 +++++------ src/flash/nor/mrvlqspi.c | 10 +++---- src/flash/nor/tcl.c | 2 +- src/jtag/drivers/arm-jtag-ew.c | 16 +++++------ src/jtag/drivers/jlink.c | 2 +- src/jtag/drivers/opendous.c | 8 +++--- src/jtag/drivers/stlink_usb.c | 6 ++-- .../usb_blaster/ublast2_access_libusb.c | 12 ++++---- src/jtag/drivers/usb_blaster/usb_blaster.c | 4 +-- src/jtag/drivers/usbprog.c | 2 +- .../drivers/versaloon/versaloon_internal.h | 2 +- src/jtag/drivers/vsllink.c | 2 +- src/jtag/minidummy/minidummy.c | 2 +- src/rtos/linux.c | 4 +-- src/server/gdb_server.c | 8 +++--- src/svf/svf.c | 8 +++--- src/target/arc_cmd.c | 28 +++++++++---------- src/target/nds32_cmd.c | 4 +-- src/target/nds32_disassembler.c | 2 +- src/target/riscv/riscv-013.c | 4 +-- 23 files changed, 74 insertions(+), 74 deletions(-) diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c index 73884b786..50ab207c1 100644 --- a/src/flash/nor/cfi.c +++ b/src/flash/nor/cfi.c @@ -2895,7 +2895,7 @@ int cfi_probe(struct flash_bank *bank) } if (offset != (cfi_info->dev_size * bank->bus_width / bank->chip_width)) { LOG_WARNING( - "CFI size is 0x%" PRIx32 ", but total sector size is 0x%" PRIx32 "", \ + "CFI size is 0x%" PRIx32 ", but total sector size is 0x%" PRIx32 "", (cfi_info->dev_size * bank->bus_width / bank->chip_width), offset); } diff --git a/src/flash/nor/fespi.c b/src/flash/nor/fespi.c index 5d8f810ad..90242b1ad 100644 --- a/src/flash/nor/fespi.c +++ b/src/flash/nor/fespi.c @@ -182,7 +182,7 @@ static int fespi_read_reg(struct flash_bank *bank, uint32_t *value, target_addr_ } static int fespi_write_reg(struct flash_bank *bank, target_addr_t address, uint32_t value) -{ \ +{ struct target *target = bank->target; struct fespi_flash_bank *fespi_info = bank->driver_priv; diff --git a/src/flash/nor/kinetis_ke.c b/src/flash/nor/kinetis_ke.c index 27b6d3a83..cfc04928b 100644 --- a/src/flash/nor/kinetis_ke.c +++ b/src/flash/nor/kinetis_ke.c @@ -814,7 +814,7 @@ static int kinetis_ke_protect_check(struct flash_bank *bank) kinfo->protection_size = 0; } else { - LOG_WARNING("Flash protected. FPOPEN=%i FPLDIS=%i FPHDIS=%i FPLS=%i FPHS=%i", \ + LOG_WARNING("Flash protected. FPOPEN=%i FPLDIS=%i FPHDIS=%i FPLS=%i FPHS=%i", fpopen ? 1 : 0, fpldis ? 1 : 0, fphdis ? 1 : 0, fpls, fphs); /* Retrieve which region is protected and how much */ diff --git a/src/flash/nor/lpcspifi.c b/src/flash/nor/lpcspifi.c index 19d754b0f..04ac3bb4d 100644 --- a/src/flash/nor/lpcspifi.c +++ b/src/flash/nor/lpcspifi.c @@ -177,8 +177,8 @@ static int lpcspifi_set_hw_mode(struct flash_bank *bank) retval = target_alloc_working_area(target, sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE, &spifi_init_algorithm); if (retval != ERROR_OK) { - LOG_ERROR("Insufficient working area to initialize SPIFI "\ - "module. You must allocate at least %zdB of working "\ + LOG_ERROR("Insufficient working area to initialize SPIFI " + "module. You must allocate at least %zdB of working " "area in order to use this driver.", sizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE ); @@ -452,7 +452,7 @@ static int lpcspifi_erase(struct flash_bank *bank, int first, int last) * it, use a bulk erase instead of going sector-by-sector. */ if (first == 0 && last == (bank->num_sectors - 1) && lpcspifi_info->dev->chip_erase_cmd != lpcspifi_info->dev->erase_cmd) { - LOG_DEBUG("Chip supports the bulk erase command."\ + LOG_DEBUG("Chip supports the bulk erase command." " Will use bulk erase instead of sector-by-sector erase."); retval = lpcspifi_bulk_erase(bank); @@ -525,7 +525,7 @@ static int lpcspifi_erase(struct flash_bank *bank, int first, int last) retval = target_alloc_working_area(target, sizeof(lpcspifi_flash_erase_code), &erase_algorithm); if (retval != ERROR_OK) { - LOG_ERROR("Insufficient working area. You must configure a working"\ + LOG_ERROR("Insufficient working area. You must configure a working" " area of at least %zdB in order to erase SPIFI flash.", sizeof(lpcspifi_flash_erase_code)); return retval; @@ -685,7 +685,7 @@ static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer, if (target_alloc_working_area(target, sizeof(lpcspifi_flash_write_code), &write_algorithm) != ERROR_OK) { - LOG_ERROR("Insufficient working area. You must configure"\ + LOG_ERROR("Insufficient working area. You must configure" " a working area > %zdB in order to write to SPIFI flash.", sizeof(lpcspifi_flash_write_code)); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; @@ -707,15 +707,15 @@ static int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer, * space, free the algorithm */ target_free_working_area(target, write_algorithm); - LOG_ERROR("Insufficient working area. Please allocate at least"\ + LOG_ERROR("Insufficient working area. Please allocate at least" " %zdB of working area to enable flash writes.", sizeof(lpcspifi_flash_write_code) + 1 ); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } else if (fifo_size < page_size) - LOG_WARNING("Working area size is limited; flash writes may be"\ - " slow. Increase working area size to at least %zdB"\ + LOG_WARNING("Working area size is limited; flash writes may be" + " slow. Increase working area size to at least %zdB" " to reduce write times.", (size_t)(sizeof(lpcspifi_flash_write_code) + page_size) ); diff --git a/src/flash/nor/mrvlqspi.c b/src/flash/nor/mrvlqspi.c index 803e84a91..7a06b3d09 100644 --- a/src/flash/nor/mrvlqspi.c +++ b/src/flash/nor/mrvlqspi.c @@ -563,7 +563,7 @@ static int mrvlqspi_flash_erase(struct flash_bank *bank, int first, int last) if (first == 0 && last == (bank->num_sectors - 1) && mrvlqspi_info->dev->chip_erase_cmd != mrvlqspi_info->dev->erase_cmd) { - LOG_DEBUG("Chip supports the bulk erase command."\ + LOG_DEBUG("Chip supports the bulk erase command." " Will use bulk erase instead of sector-by-sector erase."); retval = mrvlqspi_bulk_erase(bank); if (retval == ERROR_OK) { @@ -681,7 +681,7 @@ static int mrvlqspi_flash_write(struct flash_bank *bank, const uint8_t *buffer, if (target_alloc_working_area(target, sizeof(mrvlqspi_flash_write_code), &write_algorithm) != ERROR_OK) { - LOG_ERROR("Insufficient working area. You must configure"\ + LOG_ERROR("Insufficient working area. You must configure" " a working area > %zdB in order to write to SPIFI flash.", sizeof(mrvlqspi_flash_write_code)); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; @@ -703,15 +703,15 @@ static int mrvlqspi_flash_write(struct flash_bank *bank, const uint8_t *buffer, * space, free the algorithm */ target_free_working_area(target, write_algorithm); - LOG_ERROR("Insufficient working area. Please allocate at least"\ + LOG_ERROR("Insufficient working area. Please allocate at least" " %zdB of working area to enable flash writes.", sizeof(mrvlqspi_flash_write_code) + 1 ); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } else if (fifo_size < page_size) - LOG_WARNING("Working area size is limited; flash writes may be"\ - " slow. Increase working area size to at least %zdB"\ + LOG_WARNING("Working area size is limited; flash writes may be" + " slow. Increase working area size to at least %zdB" " to reduce write times.", (size_t)(sizeof(mrvlqspi_flash_write_code) + page_size) ); diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c index 00bfeb18e..fb2053b89 100644 --- a/src/flash/nor/tcl.c +++ b/src/flash/nor/tcl.c @@ -1028,7 +1028,7 @@ COMMAND_HANDLER(handle_flash_padded_value_command) COMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], p->default_padded_value); - command_print(CMD, "Default padded value set to 0x%" PRIx8 " for flash bank %u", \ + command_print(CMD, "Default padded value set to 0x%" PRIx8 " for flash bank %u", p->default_padded_value, p->bank_number); return retval; diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c index c81f8043b..d35e15128 100644 --- a/src/jtag/drivers/arm-jtag-ew.c +++ b/src/jtag/drivers/arm-jtag-ew.c @@ -107,7 +107,7 @@ static int armjtagew_execute_queue(void) switch (cmd->type) { case JTAG_RUNTEST: LOG_DEBUG_IO("runtest %i cycles, end in %i", - cmd->cmd.runtest->num_cycles, \ + cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); armjtagew_end_state(cmd->cmd.runtest->end_state); @@ -122,8 +122,8 @@ static int armjtagew_execute_queue(void) break; case JTAG_PATHMOVE: - LOG_DEBUG_IO("pathmove: %i states, end in %i", \ - cmd->cmd.pathmove->num_states, \ + LOG_DEBUG_IO("pathmove: %i states, end in %i", + cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); armjtagew_path_move(cmd->cmd.pathmove->num_states, @@ -459,10 +459,10 @@ static int armjtagew_get_version_info(void) auxinfo[256] = '\0'; LOG_INFO( - "ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s", \ + "ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s", usb_in_buffer[1], - usb_in_buffer[0], \ - isgraph(usb_in_buffer[2]) ? usb_in_buffer[2] : 'X', \ + usb_in_buffer[0], + isgraph(usb_in_buffer[2]) ? usb_in_buffer[2] : 'X', sn, auxinfo); @@ -750,7 +750,7 @@ static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length) return -1; } - result = usb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT, \ + result = usb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT, (char *)usb_out_buffer, out_length, ARMJTAGEW_USB_TIMEOUT); LOG_DEBUG_IO("armjtagew_usb_write, out_length = %d, result = %d", out_length, result); @@ -764,7 +764,7 @@ static int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length) /* Read data from USB into in_buffer. */ static int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length) { - int result = usb_bulk_read(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_IN, \ + int result = usb_bulk_read(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_IN, (char *)usb_in_buffer, exp_in_length, ARMJTAGEW_USB_TIMEOUT); LOG_DEBUG_IO("armjtagew_usb_read, result = %d", result); diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 3dcadc813..80202ed29 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -1525,7 +1525,7 @@ COMMAND_HANDLER(jlink_handle_config_mac_address_command) } else if (CMD_ARGC == 1) { str = CMD_ARGV[0]; - if ((strlen(str) != 17) || (str[2] != ':' || str[5] != ':' || \ + if ((strlen(str) != 17) || (str[2] != ':' || str[5] != ':' || str[8] != ':' || str[11] != ':' || str[14] != ':')) { command_print(CMD, "Invalid MAC address format."); return ERROR_COMMAND_SYNTAX_ERROR; diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index 6812ef649..bb223f417 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -259,7 +259,7 @@ static int opendous_execute_queue(void) while (cmd != NULL) { switch (cmd->type) { case JTAG_RUNTEST: - LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, \ + LOG_DEBUG_IO("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state); if (cmd->cmd.runtest->end_state != -1) @@ -276,8 +276,8 @@ static int opendous_execute_queue(void) break; case JTAG_PATHMOVE: - LOG_DEBUG_IO("pathmove: %i states, end in %i", \ - cmd->cmd.pathmove->num_states, \ + LOG_DEBUG_IO("pathmove: %i states, end in %i", + cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]); opendous_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path); @@ -770,7 +770,7 @@ int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length) LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT, FUNC_WRITE_DATA, 0, 0, (char *) usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT); } else { - jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT, \ + jtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT, (char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT, &result); } #ifdef _DEBUG_USB_COMMS_ diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 14bac2a2f..03d3da7bb 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -2319,7 +2319,7 @@ static int stlink_usb_read_mem(void *handle, uint32_t addr, uint32_t size, while (count) { - bytes_remaining = (size != 1) ? \ + bytes_remaining = (size != 1) ? stlink_max_block_size(h->max_mem_packet, addr) : stlink_usb_block(h); if (count < bytes_remaining) @@ -2404,7 +2404,7 @@ static int stlink_usb_write_mem(void *handle, uint32_t addr, uint32_t size, while (count) { - bytes_remaining = (size != 1) ? \ + bytes_remaining = (size != 1) ? stlink_max_block_size(h->max_mem_packet, addr) : stlink_usb_block(h); if (count < bytes_remaining) @@ -2528,7 +2528,7 @@ static int stlink_match_speed_map(const struct speed_map *map, unsigned int map_ match = false; if (!match && query) { - LOG_INFO("Unable to match requested speed %d kHz, using %d kHz", \ + LOG_INFO("Unable to match requested speed %d kHz, using %d kHz", khz, map[speed_index].speed); } diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c index b406c0321..e2556cec0 100644 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c @@ -45,7 +45,7 @@ static int ublast2_libusb_read(struct ublast_lowlevel *low, uint8_t *buf, int ret, tmp = 0; ret = jtag_libusb_bulk_read(low->libusb_dev, - USBBLASTER_EPIN | \ + USBBLASTER_EPIN | LIBUSB_ENDPOINT_IN, (char *)buf, size, @@ -61,7 +61,7 @@ static int ublast2_libusb_write(struct ublast_lowlevel *low, uint8_t *buf, int ret, tmp = 0; ret = jtag_libusb_bulk_write(low->libusb_dev, - USBBLASTER_EPOUT | \ + USBBLASTER_EPOUT | LIBUSB_ENDPOINT_OUT, (char *)buf, size, @@ -106,7 +106,7 @@ static int ublast2_write_firmware_section(struct libusb_device_handle *libusb_de chunk_size = bytes_remaining; jtag_libusb_control_transfer(libusb_dev, - LIBUSB_REQUEST_TYPE_VENDOR | \ + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, USBBLASTER_CTRL_LOAD_FIRM, addr, @@ -152,7 +152,7 @@ static int load_usb_blaster_firmware(struct libusb_device_handle *libusb_dev, char value = CPU_RESET; jtag_libusb_control_transfer(libusb_dev, - LIBUSB_REQUEST_TYPE_VENDOR | \ + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, USBBLASTER_CTRL_LOAD_FIRM, EZUSB_CPUCS, @@ -173,7 +173,7 @@ static int load_usb_blaster_firmware(struct libusb_device_handle *libusb_dev, value = !CPU_RESET; jtag_libusb_control_transfer(libusb_dev, - LIBUSB_REQUEST_TYPE_VENDOR | \ + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, USBBLASTER_CTRL_LOAD_FIRM, EZUSB_CPUCS, @@ -230,7 +230,7 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low) char buffer[5]; jtag_libusb_control_transfer(low->libusb_dev, - LIBUSB_REQUEST_TYPE_VENDOR | \ + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN, USBBLASTER_CTRL_READ_REV, 0, diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c index fcb594f30..d30483b63 100644 --- a/src/jtag/drivers/usb_blaster/usb_blaster.c +++ b/src/jtag/drivers/usb_blaster/usb_blaster.c @@ -1042,8 +1042,8 @@ static const struct command_registration ublast_command_handlers[] = { .name = "usb_blaster_vid_pid", .handler = ublast_handle_vid_pid_command, .mode = COMMAND_CONFIG, - .help = "the vendor ID and product ID of the USB-Blaster and " \ - "vendor ID and product ID of the uninitialized device " \ + .help = "the vendor ID and product ID of the USB-Blaster and " + "vendor ID and product ID of the uninitialized device " "for USB-Blaster II", .usage = "vid pid vid_uninit pid_uninit", }, diff --git a/src/jtag/drivers/usbprog.c b/src/jtag/drivers/usbprog.c index 6517ce4ad..7b27eaff2 100644 --- a/src/jtag/drivers/usbprog.c +++ b/src/jtag/drivers/usbprog.c @@ -381,7 +381,7 @@ static void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag) static unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen) { int res = usb_bulk_write(usbprog_jtag->usb_handle, 3, msg, msglen, 100); - if ((msg[0] == 2) || (msg[0] == 1) || (msg[0] == 4) || (msg[0] == 0) || \ + if ((msg[0] == 2) || (msg[0] == 1) || (msg[0] == 4) || (msg[0] == 0) || (msg[0] == 6) || (msg[0] == 0x0A) || (msg[0] == 9)) return 1; if (res == msglen) { diff --git a/src/jtag/drivers/versaloon/versaloon_internal.h b/src/jtag/drivers/versaloon/versaloon_internal.h index 497b6b9ce..8372970b1 100644 --- a/src/jtag/drivers/versaloon/versaloon_internal.h +++ b/src/jtag/drivers/versaloon/versaloon_internal.h @@ -91,7 +91,7 @@ struct versaloon_pending_t { void *extra_data; versaloon_callback_t callback; }; -extern struct versaloon_pending_t \ +extern struct versaloon_pending_t versaloon_pending[VERSALOON_MAX_PENDING_NUMBER]; extern uint16_t versaloon_pending_idx; void versaloon_set_pending_id(uint32_t id); diff --git a/src/jtag/drivers/vsllink.c b/src/jtag/drivers/vsllink.c index eb4370233..5fb9bcdcc 100644 --- a/src/jtag/drivers/vsllink.c +++ b/src/jtag/drivers/vsllink.c @@ -292,7 +292,7 @@ static int vsllink_interface_init(void) libusb_init(&vsllink_handle->libusb_ctx); if (ERROR_OK != vsllink_usb_open(vsllink_handle)) { - LOG_ERROR("Can't find USB JTAG Interface!" \ + LOG_ERROR("Can't find USB JTAG Interface!" "Please check connection and permissions."); return ERROR_JTAG_INIT_FAILED; } diff --git a/src/jtag/minidummy/minidummy.c b/src/jtag/minidummy/minidummy.c index 1fce317f0..7d5e6a98a 100644 --- a/src/jtag/minidummy/minidummy.c +++ b/src/jtag/minidummy/minidummy.c @@ -170,7 +170,7 @@ void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *bu 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, \ + 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); } diff --git a/src/rtos/linux.c b/src/rtos/linux.c index 9e59c41a5..0f18d171c 100644 --- a/src/rtos/linux.c +++ b/src/rtos/linux.c @@ -1379,8 +1379,8 @@ static int linux_thread_packet(struct connection *connection, char const *packet target->rtos-> current_threadid) && (target->rtos->current_threadid != -1)) - LOG_WARNING("WARNING! current GDB thread do not match" \ - "current thread running." \ + LOG_WARNING("WARNING! current GDB thread do not match" + "current thread running." "Switch thread in GDB to threadid %d", (int)ct->threadid); diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index f9fe4c293..6a9e261cd 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1004,7 +1004,7 @@ static int gdb_new_connection(struct connection *connection) continue; retval = get_flash_bank_by_num(i, &p); if (retval != ERROR_OK) { - LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target " \ + LOG_ERROR("Connect failed. Consider setting up a gdb-attach event for the target " "to prepare target for GDB connect, or use 'gdb_memory_map disable'."); return retval; } @@ -2857,7 +2857,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p if (gdb_connection->sync) { gdb_connection->sync = false; if (ct->state == TARGET_HALTED) { - LOG_DEBUG("stepi ignored. GDB will now fetch the register state " \ + LOG_DEBUG("stepi ignored. GDB will now fetch the register state " "from the target."); gdb_sig_halted(connection); log_remove_callback(gdb_log_callback, connection); @@ -3330,7 +3330,7 @@ static int gdb_input_inner(struct connection *connection) "Waiting for target to halt."); already_running = true; } else if (target->state != TARGET_HALTED) { - LOG_WARNING("The target is not in the halted nor running stated, " \ + LOG_WARNING("The target is not in the halted nor running stated, " "stepi/continue ignored."); nostep = true; } else if ((packet[0] == 's') && gdb_con->sync) { @@ -3339,7 +3339,7 @@ static int gdb_input_inner(struct connection *connection) * make only the single stepping have the sync feature... */ nostep = true; - LOG_DEBUG("stepi ignored. GDB will now fetch the register state " \ + LOG_DEBUG("stepi ignored. GDB will now fetch the register state " "from the target."); } gdb_con->sync = false; diff --git a/src/svf/svf.c b/src/svf/svf.c index 54fc7d139..fd27417e0 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -1540,8 +1540,8 @@ XXR_common: if (debug_level >= LOG_LVL_DEBUG) { /* for convenient debugging, execute tap if possible */ - if ((svf_buffer_index > 0) && \ - (((command != STATE) && (command != RUNTEST)) || \ + if ((svf_buffer_index > 0) && + (((command != STATE) && (command != RUNTEST)) || ((command == STATE) && (num_of_argu == 2)))) { if (ERROR_OK != svf_execute_tap()) return ERROR_FAIL; @@ -1555,8 +1555,8 @@ XXR_common: /* for fast executing, execute tap if necessary */ /* half of the buffer is for the next command */ if (((svf_buffer_index >= SVF_MAX_BUFFER_SIZE_TO_COMMIT) || - (svf_check_tdo_para_index >= SVF_CHECK_TDO_PARA_SIZE / 2)) && \ - (((command != STATE) && (command != RUNTEST)) || \ + (svf_check_tdo_para_index >= SVF_CHECK_TDO_PARA_SIZE / 2)) && + (((command != STATE) && (command != RUNTEST)) || ((command == STATE) && (num_of_argu == 2)))) return svf_execute_tap(); } diff --git a/src/target/arc_cmd.c b/src/target/arc_cmd.c index a8c3bb43a..fad8ca947 100644 --- a/src/target/arc_cmd.c +++ b/src/target/arc_cmd.c @@ -383,7 +383,7 @@ static int jim_arc_get_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *a /* Register number */ JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); if (regnum > CORE_REG_MAX_NUMBER || regnum == CORE_R61_NUM || regnum == CORE_R62_NUM) { - Jim_SetResultFormatted(goi.interp, "Core register number %i " \ + Jim_SetResultFormatted(goi.interp, "Core register number %i " "is invalid. Must less then 64 and not 61 and 62.", regnum); return JIM_ERR; } @@ -426,7 +426,7 @@ static int jim_arc_set_core_reg(Jim_Interp *interp, int argc, Jim_Obj * const *a /* Register number */ JIM_CHECK_RETVAL(arc_cmd_jim_get_uint32(&goi, ®num)); if (regnum > CORE_REG_MAX_NUMBER || regnum == CORE_R61_NUM || regnum == CORE_R62_NUM) { - Jim_SetResultFormatted(goi.interp, "Core register number %i " \ + Jim_SetResultFormatted(goi.interp, "Core register number %i " "is invalid. Must less then 64 and not 61 and 62.", regnum); return JIM_ERR; } @@ -447,9 +447,9 @@ static const struct command_registration arc_jtag_command_group[] = { .name = "get-aux-reg", .jim_handler = jim_arc_get_aux_reg, .mode = COMMAND_EXEC, - .help = "Get AUX register by number. This command does a " \ - "raw JTAG request that bypasses OpenOCD register cache "\ - "and thus is unsafe and can have unexpected consequences. "\ + .help = "Get AUX register by number. This command does a " + "raw JTAG request that bypasses OpenOCD register cache " + "and thus is unsafe and can have unexpected consequences. " "Use at your own risk.", .usage = "arc jtag get-aux-reg " }, @@ -457,9 +457,9 @@ static const struct command_registration arc_jtag_command_group[] = { .name = "set-aux-reg", .jim_handler = jim_arc_set_aux_reg, .mode = COMMAND_EXEC, - .help = "Set AUX register by number. This command does a " \ - "raw JTAG request that bypasses OpenOCD register cache "\ - "and thus is unsafe and can have unexpected consequences. "\ + .help = "Set AUX register by number. This command does a " + "raw JTAG request that bypasses OpenOCD register cache " + "and thus is unsafe and can have unexpected consequences. " "Use at your own risk.", .usage = "arc jtag set-aux-reg " }, @@ -467,9 +467,9 @@ static const struct command_registration arc_jtag_command_group[] = { .name = "get-core-reg", .jim_handler = jim_arc_get_core_reg, .mode = COMMAND_EXEC, - .help = "Get/Set core register by number. This command does a " \ - "raw JTAG request that bypasses OpenOCD register cache "\ - "and thus is unsafe and can have unexpected consequences. "\ + .help = "Get/Set core register by number. This command does a " + "raw JTAG request that bypasses OpenOCD register cache " + "and thus is unsafe and can have unexpected consequences. " "Use at your own risk.", .usage = "arc jtag get-core-reg []" }, @@ -477,9 +477,9 @@ static const struct command_registration arc_jtag_command_group[] = { .name = "set-core-reg", .jim_handler = jim_arc_set_core_reg, .mode = COMMAND_EXEC, - .help = "Get/Set core register by number. This command does a " \ - "raw JTAG request that bypasses OpenOCD register cache "\ - "and thus is unsafe and can have unexpected consequences. "\ + .help = "Get/Set core register by number. This command does a " + "raw JTAG request that bypasses OpenOCD register cache " + "and thus is unsafe and can have unexpected consequences. " "Use at your own risk.", .usage = "arc jtag set-core-reg []" }, diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c index 88d8b4512..7bf7e60c7 100644 --- a/src/target/nds32_cmd.c +++ b/src/target/nds32_cmd.c @@ -1007,7 +1007,7 @@ static const struct command_registration nds32_exec_command_handlers[] = { .handler = handle_nds32_global_stop_command, .mode = COMMAND_ANY, .usage = "['on'|'off']", - .help = "turn on/off global stop. After turning on, every load/store" \ + .help = "turn on/off global stop. After turning on, every load/store" "instructions will be stopped to check memory access.", }, { @@ -1015,7 +1015,7 @@ static const struct command_registration nds32_exec_command_handlers[] = { .handler = handle_nds32_soft_reset_halt_command, .mode = COMMAND_ANY, .usage = "['on'|'off']", - .help = "as issuing rest-halt, to use soft-reset-halt or not." \ + .help = "as issuing rest-halt, to use soft-reset-halt or not." "the feature is for backward-compatible.", }, { diff --git a/src/target/nds32_disassembler.c b/src/target/nds32_disassembler.c index f27aba2cc..0cfd197d2 100644 --- a/src/target/nds32_disassembler.c +++ b/src/target/nds32_disassembler.c @@ -493,7 +493,7 @@ static int nds32_parse_mem(struct nds32 *nds32, uint32_t opcode, uint32_t addres switch (sub_opcode & 0x7) { case 0: /* LB */ nds32_parse_type_3(opcode, &(instruction->info.rt), - &(instruction->info.ra), \ + &(instruction->info.ra), &(instruction->info.rb), &(instruction->info.imm)); instruction->type = NDS32_INSN_LOAD_STORE; nds32_get_mapped_reg(nds32, instruction->info.ra, &val_ra); diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index e30294114..4a323e4ee 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -3712,13 +3712,13 @@ int riscv013_test_compliance(struct target *target) But at any rate, this is not legal and should cause an error. */ COMPLIANCE_WRITE(target, DMI_COMMAND, 0xAAAAAAAA); COMPLIANCE_READ(target, &testvar_read, DMI_ABSTRACTCS); - COMPLIANCE_TEST(get_field(testvar_read, DMI_ABSTRACTCS_CMDERR) == CMDERR_NOT_SUPPORTED, \ + COMPLIANCE_TEST(get_field(testvar_read, DMI_ABSTRACTCS_CMDERR) == CMDERR_NOT_SUPPORTED, "Illegal COMMAND should result in UNSUPPORTED"); COMPLIANCE_WRITE(target, DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR); COMPLIANCE_WRITE(target, DMI_COMMAND, 0x55555555); COMPLIANCE_READ(target, &testvar_read, DMI_ABSTRACTCS); - COMPLIANCE_TEST(get_field(testvar_read, DMI_ABSTRACTCS_CMDERR) == CMDERR_NOT_SUPPORTED, \ + COMPLIANCE_TEST(get_field(testvar_read, DMI_ABSTRACTCS_CMDERR) == CMDERR_NOT_SUPPORTED, "Illegal COMMAND should result in UNSUPPORTED"); COMPLIANCE_WRITE(target, DMI_ABSTRACTCS, DMI_ABSTRACTCS_CMDERR); From 185834ef8aa663faf6761e5c3d7c4a049c88eeab Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 12:18:30 +0200 Subject: [PATCH 298/354] coding style: add missing space when split strings Long strings are split across few lines; usually split occurs at the white space between two words. Check that the space between the two words is still present. While there, adjust the amount of space between words. Issue identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types MISSING_SPACE -f {} \; Change-Id: I28b9a65564195ba967051add53d1c848c7b8fb30 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5620 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/flash/nor/at91sam3.c | 2 +- src/flash/nor/at91sam4.c | 2 +- src/helper/command.c | 6 +++--- src/rtos/ChibiOS.c | 2 +- src/rtos/linux.c | 4 ++-- src/target/nds32_cmd.c | 2 +- src/target/riscv/riscv.c | 12 ++++++------ src/target/target.c | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c index b51e0972a..c9ffa653b 100644 --- a/src/flash/nor/at91sam3.c +++ b/src/flash/nor/at91sam3.c @@ -3726,7 +3726,7 @@ static const struct command_registration at91sam3_exec_command_handlers[] = { .name = "info", .handler = sam3_handle_info_command, .mode = COMMAND_EXEC, - .help = "Print information about the current at91sam3 chip" + .help = "Print information about the current at91sam3 chip " "and its flash configuration.", .usage = "", }, diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c index 135fc99bf..5b56c4241 100644 --- a/src/flash/nor/at91sam4.c +++ b/src/flash/nor/at91sam4.c @@ -3206,7 +3206,7 @@ static const struct command_registration at91sam4_exec_command_handlers[] = { .name = "info", .handler = sam4_handle_info_command, .mode = COMMAND_EXEC, - .help = "Print information about the current at91sam4 chip" + .help = "Print information about the current at91sam4 chip " "and its flash configuration.", .usage = "", }, diff --git a/src/helper/command.c b/src/helper/command.c index 0882ecd58..4422b4abe 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -1219,9 +1219,9 @@ static const struct command_registration command_subcommand_handlers[] = { .mode = COMMAND_ANY, .jim_handler = jim_command_mode, .usage = "[command_name ...]", - .help = "Returns the command modes allowed by a command:" - "'any', 'config', or 'exec'. If no command is" - "specified, returns the current command mode. " + .help = "Returns the command modes allowed by a command: " + "'any', 'config', or 'exec'. If no command is " + "specified, returns the current command mode. " "Returns 'unknown' if an unknown command is given. " "Command can be multiple tokens.", }, diff --git a/src/rtos/ChibiOS.c b/src/rtos/ChibiOS.c index 8839acc9a..08b234fa9 100644 --- a/src/rtos/ChibiOS.c +++ b/src/rtos/ChibiOS.c @@ -200,7 +200,7 @@ static int ChibiOS_update_memory_signature(struct rtos *rtos) /* Currently, we have the inherent assumption that all address pointers * are 32 bit wide. */ if (signature->ch_ptrsize != sizeof(uint32_t)) { - LOG_ERROR("ChibiOS/RT target memory signature claims an address" + LOG_ERROR("ChibiOS/RT target memory signature claims an address " "width unequal to 32 bits!"); free(signature); return -1; diff --git a/src/rtos/linux.c b/src/rtos/linux.c index 0f18d171c..e85a3bdf8 100644 --- a/src/rtos/linux.c +++ b/src/rtos/linux.c @@ -1379,8 +1379,8 @@ static int linux_thread_packet(struct connection *connection, char const *packet target->rtos-> current_threadid) && (target->rtos->current_threadid != -1)) - LOG_WARNING("WARNING! current GDB thread do not match" - "current thread running." + LOG_WARNING("WARNING! current GDB thread do not match " + "current thread running. " "Switch thread in GDB to threadid %d", (int)ct->threadid); diff --git a/src/target/nds32_cmd.c b/src/target/nds32_cmd.c index 7bf7e60c7..d7d040e4b 100644 --- a/src/target/nds32_cmd.c +++ b/src/target/nds32_cmd.c @@ -1007,7 +1007,7 @@ static const struct command_registration nds32_exec_command_handlers[] = { .handler = handle_nds32_global_stop_command, .mode = COMMAND_ANY, .usage = "['on'|'off']", - .help = "turn on/off global stop. After turning on, every load/store" + .help = "turn on/off global stop. After turning on, every load/store " "instructions will be stopped to check memory access.", }, { diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 7ad1ccde9..b5fd22b48 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1858,13 +1858,13 @@ static const struct command_registration riscv_exec_command_handlers[] = { .name = "test_sba_config_reg", .handler = riscv_test_sba_config_reg, .mode = COMMAND_ANY, - .usage = "riscv test_sba_config_reg legal_address num_words" + .usage = "riscv test_sba_config_reg legal_address num_words " "illegal_address run_sbbusyerror_test[on/off]", - .help = "Perform a series of tests on the SBCS register." - "Inputs are a legal, 128-byte aligned address and a number of words to" - "read/write starting at that address (i.e., address range [legal address," - "legal_address+word_size*num_words) must be legally readable/writable)" - ", an illegal, 128-byte aligned address for error flag/handling cases," + .help = "Perform a series of tests on the SBCS register. " + "Inputs are a legal, 128-byte aligned address and a number of words to " + "read/write starting at that address (i.e., address range [legal address, " + "legal_address+word_size*num_words) must be legally readable/writable), " + "an illegal, 128-byte aligned address for error flag/handling cases, " "and whether sbbusyerror test should be run." }, { diff --git a/src/target/target.c b/src/target/target.c index 538831b5b..b0deadb0b 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -6232,7 +6232,7 @@ static const struct command_registration target_exec_command_handlers[] = { .name = "halt", .handler = handle_halt_command, .mode = COMMAND_EXEC, - .help = "request target to halt, then wait up to the specified" + .help = "request target to halt, then wait up to the specified " "number of milliseconds (default 5000) for it to complete", .usage = "[milliseconds]", }, @@ -6248,7 +6248,7 @@ static const struct command_registration target_exec_command_handlers[] = { .handler = handle_reset_command, .mode = COMMAND_EXEC, .usage = "[run|halt|init]", - .help = "Reset all targets into the specified mode." + .help = "Reset all targets into the specified mode. " "Default reset mode is run, if not given.", }, { From 3474aa223a712ac848a8a8e58633106477db0641 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 12:31:57 +0200 Subject: [PATCH 299/354] coding style: prototype of functions with no parameters Functions that have no parameters should use "void" as parameter in the function declaration. Issue identified and fixed by script checkpatch from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types FUNCTION_WITHOUT_ARGS --fix-inplace -f {} \; Change-Id: If104ac75b44e939ec86155ff7b5720f2e33c6b39 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5621 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/helper/log.c | 4 ++-- src/jtag/core.c | 4 ++-- src/jtag/drivers/arm-jtag-ew.c | 2 +- src/jtag/interface.c | 4 ++-- src/jtag/minidummy/minidummy.c | 2 +- src/jtag/zy1000/zy1000.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/helper/log.c b/src/helper/log.c index ae26df5a1..380f548f4 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -401,7 +401,7 @@ char *alloc_printf(const char *format, ...) * fast when invoked more often than every 500ms. * */ -void keep_alive() +void keep_alive(void) { current_time = timeval_ms(); if (current_time-last_time > 1000) { @@ -436,7 +436,7 @@ void keep_alive() } /* reset keep alive timer without sending message */ -void kept_alive() +void kept_alive(void) { current_time = timeval_ms(); last_time = current_time; diff --git a/src/jtag/core.c b/src/jtag/core.c index f12ab5924..884a74365 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1872,7 +1872,7 @@ void jtag_set_verify(bool enable) jtag_verify = enable; } -bool jtag_will_verify() +bool jtag_will_verify(void) { return jtag_verify; } @@ -1882,7 +1882,7 @@ void jtag_set_verify_capture_ir(bool enable) jtag_verify_capture_ir = enable; } -bool jtag_will_verify_capture_ir() +bool jtag_will_verify_capture_ir(void) { return jtag_verify_capture_ir; } diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c index d35e15128..405278b9a 100644 --- a/src/jtag/drivers/arm-jtag-ew.c +++ b/src/jtag/drivers/arm-jtag-ew.c @@ -683,7 +683,7 @@ static int armjtagew_tap_execute(void) /**************************************************************************** * JLink USB low-level functions */ -static struct armjtagew *armjtagew_usb_open() +static struct armjtagew *armjtagew_usb_open(void) { usb_init(); diff --git a/src/jtag/interface.c b/src/jtag/interface.c index de132bbe8..56bbf6e51 100644 --- a/src/jtag/interface.c +++ b/src/jtag/interface.c @@ -45,7 +45,7 @@ void tap_set_state_impl(tap_state_t new_state) state_follower = new_state; } -tap_state_t tap_get_state() +tap_state_t tap_get_state(void) { return state_follower; } @@ -64,7 +64,7 @@ void tap_set_end_state(tap_state_t new_end_state) end_state_follower = new_end_state; } -tap_state_t tap_get_end_state() +tap_state_t tap_get_end_state(void) { return end_state_follower; } diff --git a/src/jtag/minidummy/minidummy.c b/src/jtag/minidummy/minidummy.c index 7d5e6a98a..7ee206732 100644 --- a/src/jtag/minidummy/minidummy.c +++ b/src/jtag/minidummy/minidummy.c @@ -83,7 +83,7 @@ int interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, return ERROR_OK; } -int interface_jtag_add_tlr() +int interface_jtag_add_tlr(void) { /* synchronously do the operation here */ diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index 48a3d4d03..37af2f7ae 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -486,7 +486,7 @@ int interface_jtag_add_plain_dr_scan(int num_bits, return ERROR_OK; } -int interface_jtag_add_tlr() +int interface_jtag_add_tlr(void) { setCurrentState(TAP_RESET); return ERROR_OK; From 3883e769f43fe85d1d499c8ac7ae2ed781bf137d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 12:41:22 +0200 Subject: [PATCH 300/354] coding style: remove useless return statement from void functions For void functions, a return as last statement is useless. Remove it. Issue identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types RETURN_VOID -f {} \; Change-Id: Ie0616fe98623f30d2d7b04ac9517d669774092de Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5622 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/jtag/drivers/cmsis_dap_usb.c | 2 -- src/jtag/drivers/sysfsgpio.c | 2 -- src/jtag/drivers/xds110.c | 11 ----------- 3 files changed, 15 deletions(-) diff --git a/src/jtag/drivers/cmsis_dap_usb.c b/src/jtag/drivers/cmsis_dap_usb.c index 289737754..ee1cb533c 100644 --- a/src/jtag/drivers/cmsis_dap_usb.c +++ b/src/jtag/drivers/cmsis_dap_usb.c @@ -364,8 +364,6 @@ static void cmsis_dap_usb_close(struct cmsis_dap *dap) free(pending_fifo[i].transfers); pending_fifo[i].transfers = NULL; } - - return; } static int cmsis_dap_usb_write(struct cmsis_dap *dap, int txlen) diff --git a/src/jtag/drivers/sysfsgpio.c b/src/jtag/drivers/sysfsgpio.c index e4a15237b..a4d7ad9ec 100644 --- a/src/jtag/drivers/sysfsgpio.c +++ b/src/jtag/drivers/sysfsgpio.c @@ -98,8 +98,6 @@ static void unexport_sysfs_gpio(int gpio) snprintf(gpiostr, sizeof(gpiostr), "%d", gpio); if (open_write_close("/sys/class/gpio/unexport", gpiostr) < 0) LOG_ERROR("Couldn't unexport gpio %d", gpio); - - return; } /* diff --git a/src/jtag/drivers/xds110.c b/src/jtag/drivers/xds110.c index 8a832adf0..5e4df93c2 100644 --- a/src/jtag/drivers/xds110.c +++ b/src/jtag/drivers/xds110.c @@ -1683,14 +1683,11 @@ static int xds110_reset(int trst, int srst) static void xds110_execute_sleep(struct jtag_command *cmd) { jtag_sleep(cmd->cmd.sleep->us); - return; } static void xds110_execute_tlr_reset(struct jtag_command *cmd) { (void)xds_goto_state(XDS_JTAG_STATE_RESET); - - return; } static void xds110_execute_pathmove(struct jtag_command *cmd) @@ -1726,8 +1723,6 @@ static void xds110_execute_pathmove(struct jtag_command *cmd) } free((void *)path); - - return; } static void xds110_queue_scan(struct jtag_command *cmd) @@ -1799,8 +1794,6 @@ static void xds110_queue_scan(struct jtag_command *cmd) } xds110.txn_request_size += total_bytes; xds110.txn_result_size += total_bytes; - - return; } static void xds110_queue_runtest(struct jtag_command *cmd) @@ -1820,8 +1813,6 @@ static void xds110_queue_runtest(struct jtag_command *cmd) xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff; xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff; xds110.txn_requests[xds110.txn_request_size++] = end_state; - - return; } static void xds110_queue_stableclocks(struct jtag_command *cmd) @@ -1838,8 +1829,6 @@ static void xds110_queue_stableclocks(struct jtag_command *cmd) xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 8) & 0xff; xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff; xds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff; - - return; } static void xds110_execute_command(struct jtag_command *cmd) From 1946b50dba6c9d5bd5fda2b396eeae649b47762a Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 12:56:38 +0200 Subject: [PATCH 301/354] coding style: let "else" follow the close brace The statement "else" should not be on a new line when follows a close brace '}'. Fix it! Issue identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types ELSE_AFTER_BRACE -f {} \; Change-Id: I8af247ec3f75a69713d7cb1e73881254d16c189e Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5623 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/flash/nor/stm32f1x.c | 3 +-- src/target/cortex_m.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index 37dcafd87..990b48aeb 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -1369,8 +1369,7 @@ COMMAND_HANDLER(stm32x_handle_options_write_command) COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], useropt); CMD_ARGC--; CMD_ARGV++; - } - else if (stm32x_info->has_dual_banks) { + } else if (stm32x_info->has_dual_banks) { if (strcmp("BOOT0", CMD_ARGV[0]) == 0) optionbyte |= (1 << 3); else if (strcmp("BOOT1", CMD_ARGV[0]) == 0) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 27febd3d7..bb14bc846 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -966,8 +966,7 @@ static int cortex_m_step(struct target *target, int current, /* Re-enable interrupts if appropriate */ cortex_m_write_debug_halt_mask(target, C_HALT, 0); cortex_m_set_maskints_for_halt(target); - } - else { + } else { /* Set a temporary break point */ if (breakpoint) { From 4625257007b520c739a9e9437b97c7c7c7d60158 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 14:37:19 +0200 Subject: [PATCH 302/354] coding style: join consecutive string fragments The re is no need to split a long string, apart for fitting the predefined line width. Join the consecutive string fragments. Issue identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types STRING_FRAGMENTS -f {} \; Change-Id: I8de52d572b0e3d4788c1d4d2b0cf8f94c7f08409 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5625 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/jtag/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/core.c b/src/jtag/core.c index 884a74365..d83f19503 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -1406,7 +1406,7 @@ static int jtag_validate_ircapture(void) && tap->ir_length < JTAG_IRLEN_MAX) { tap->ir_length++; } - LOG_WARNING("AUTO %s - use \"jtag newtap " "%s %s -irlen %d " + LOG_WARNING("AUTO %s - use \"jtag newtap %s %s -irlen %d " "-expected-id 0x%08" PRIx32 "\"", tap->dotted_name, tap->chip, tap->tapname, tap->ir_length, tap->idcode); } From e41c3f78d13b9450c5c96d7188d8ec775df8f4ad Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 15:07:19 +0200 Subject: [PATCH 303/354] coding style: wrap lines longer than 120 chars The coding style is quite permissive allowing 120 chars per line, but abuses are still present. Fix them, wrapping the lines. Change-Id: I94d66b651d759a60ec35f7ba115c43933e70ed69 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5626 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/target/dsp563xx_once.c | 3 ++- src/target/dsp5680xx.c | 13 +++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/target/dsp563xx_once.c b/src/target/dsp563xx_once.c index 65ef7070b..624474d1b 100644 --- a/src/target/dsp563xx_once.c +++ b/src/target/dsp563xx_once.c @@ -66,7 +66,8 @@ static inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t *dr_in, u } /** single word instruction */ -static inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex) +static inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t instr, + uint8_t rw, uint8_t go, uint8_t ex) { int err; diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c index a50f2cd47..c74a41846 100644 --- a/src/target/dsp5680xx.c +++ b/src/target/dsp5680xx.c @@ -1731,7 +1731,12 @@ static int dsp5680xx_f_ex(struct target *t, uint16_t c, uint32_t a, uint32_t d, } /** - * Prior to the execution of any Flash module command, the Flash module Clock Divider (CLKDIV) register must be initialized. The values of this register determine the speed of the internal Flash Clock (FCLK). FCLK must be in the range of 150kHz ≤ FCLK ≤ 200kHz for proper operation of the Flash module. (Running FCLK too slowly wears out the module, while running it too fast under programs Flash leading to bit errors.) + * Prior to the execution of any Flash module command, the Flash module Clock + * Divider (CLKDIV) register must be initialized. The values of this register + * determine the speed of the internal Flash Clock (FCLK). FCLK must be in the + * range of 150kHz ≤ FCLK ≤ 200kHz for proper operation of the Flash module. + * (Running FCLK too slowly wears out the module, while running it too fast + * under programs Flash leading to bit errors.) * * @param target * @@ -1787,7 +1792,11 @@ static int set_fm_ck_div(struct target *target) } /** - * Executes the FM calculate signature command. The FM will calculate over the data from @address to @address + @words -1. The result is written to a register, then read out by this function and returned in @signature. The value @signature may be compared to the the one returned by perl_crc to verify the flash was written correctly. + * Executes the FM calculate signature command. The FM will calculate over the + * data from @address to @address + @words -1. The result is written to a + * register, then read out by this function and returned in @signature. The + * value @signature may be compared to the the one returned by perl_crc to + * verify the flash was written correctly. * * @param target * @param address Start of flash array where the signature should be calculated. From 59cc1f6629a8d8008cd5af69792e63adecd56b7c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 18:32:02 +0200 Subject: [PATCH 304/354] coding style: open function's brace at beginning of new line Issue identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types OPEN_BRACE -f {} \; Change-Id: I6d1356ed11e2699525f384efb7556bc2efdc299f Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5628 Tested-by: jenkins Reviewed-by: Marc Schink --- src/target/openrisc/or1k.c | 4 ++-- src/target/riscv/riscv.c | 28 +++++++++------------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/src/target/openrisc/or1k.c b/src/target/openrisc/or1k.c index 1e5db8c61..44825d002 100644 --- a/src/target/openrisc/or1k.c +++ b/src/target/openrisc/or1k.c @@ -1207,8 +1207,8 @@ int or1k_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *file } static int or1k_checksum_memory(struct target *target, target_addr_t address, - uint32_t count, uint32_t *checksum) { - + uint32_t count, uint32_t *checksum) +{ return ERROR_FAIL; } diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index b5fd22b48..afd0cc815 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -772,12 +772,9 @@ static int oldriscv_step(struct target *target, int current, uint32_t address, return tt->step(target, current, address, handle_breakpoints); } -static int old_or_new_riscv_step( - struct target *target, - int current, - target_addr_t address, - int handle_breakpoints -){ +static int old_or_new_riscv_step(struct target *target, int current, + target_addr_t address, int handle_breakpoints) +{ RISCV_INFO(r); LOG_DEBUG("handle_breakpoints=%d", handle_breakpoints); if (r->is_halted == NULL) @@ -862,13 +859,9 @@ static int oldriscv_resume(struct target *target, int current, uint32_t address, debug_execution); } -static int old_or_new_riscv_resume( - struct target *target, - int current, - target_addr_t address, - int handle_breakpoints, - int debug_execution -){ +static int old_or_new_riscv_resume(struct target *target, int current, + target_addr_t address, int handle_breakpoints, int debug_execution) +{ LOG_DEBUG("handle_breakpoints=%d", handle_breakpoints); if (target->smp) { struct target_list *targets = target->head; @@ -1413,12 +1406,9 @@ int riscv_openocd_resume( return out; } -int riscv_openocd_step( - struct target *target, - int current, - target_addr_t address, - int handle_breakpoints -) { +int riscv_openocd_step(struct target *target, int current, + target_addr_t address, int handle_breakpoints) +{ LOG_DEBUG("stepping rtos hart"); if (!current) From b604bc6c4ccaf81d61cd1c8a5e5c9f1b722e252e Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Thu, 20 Feb 2020 21:55:53 +0100 Subject: [PATCH 305/354] flash/nor/bluenrg-x: Minor code cleanups Change-Id: I7844eb30d58b0a23ca5bcc94181066cca6fa0861 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5462 Tested-by: jenkins Reviewed-by: Tomas Vanek --- src/flash/nor/bluenrg-x.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/flash/nor/bluenrg-x.c b/src/flash/nor/bluenrg-x.c index f7f5e6370..fbce20d55 100644 --- a/src/flash/nor/bluenrg-x.c +++ b/src/flash/nor/bluenrg-x.c @@ -74,7 +74,7 @@ const struct flash_ctrl_priv_data flash_priv_data_lp = { }; struct bluenrgx_flash_bank { - int probed; + bool probed; uint32_t die_id; const struct flash_ctrl_priv_data *flash_ptr; }; @@ -99,7 +99,7 @@ FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command) bank->driver_priv = bluenrgx_info; - bluenrgx_info->probed = 0; + bluenrgx_info->probed = false; if (CMD_ARGC < 6) return ERROR_COMMAND_SYNTAX_ERROR; @@ -133,7 +133,7 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last) uint32_t address, command; /* check preconditions */ - if (bluenrgx_info->probed == 0) + if (!bluenrgx_info->probed) return ERROR_FLASH_BANK_NOT_PROBED; if (bank->target->state != TARGET_HALTED) { @@ -165,7 +165,7 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last) return ERROR_FAIL; } - for (int i = 0; i < 100; i++) { + for (unsigned int i = 0; i < 100; i++) { uint32_t value; if (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) { LOG_ERROR("Register write failed"); @@ -201,7 +201,7 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last) return ERROR_FAIL; } - for (int j = 0; j < 100; j++) { + for (unsigned int j = 0; j < 100; j++) { uint32_t value; if (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) { LOG_ERROR("Register write failed"); @@ -244,7 +244,7 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, }; /* check preconditions */ - if (bluenrgx_info->probed == 0) + if (!bluenrgx_info->probed) return ERROR_FLASH_BANK_NOT_PROBED; if ((offset + count) > bank->size) { @@ -365,7 +365,6 @@ static int bluenrgx_probe(struct flash_bank *bank) { struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; uint32_t idcode, size_info, die_id; - int i; int retval = target_read_u32(bank->target, BLUENRGLP_JTAG_REG, &idcode); if (retval != ERROR_OK) @@ -381,7 +380,7 @@ static int bluenrgx_probe(struct flash_bank *bank) bluenrgx_info->flash_ptr = &flash_priv_data_1; bank->base = flash_priv_data_1.flash_base; - for (i = 0; i < (int)(sizeof(flash_ctrl)/sizeof(*flash_ctrl)); i++) { + for (size_t i = 0; i < ARRAY_SIZE(flash_ctrl); i++) { if (idcode == (*flash_ctrl[i]).jtag_idcode) { bluenrgx_info->flash_ptr = flash_ctrl[i]; bank->base = (*flash_ctrl[i]).flash_base; @@ -400,14 +399,14 @@ static int bluenrgx_probe(struct flash_bank *bank) bank->num_sectors = bank->size/FLASH_PAGE_SIZE(bluenrgx_info); bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector) * bank->num_sectors); - for (i = 0; i < bank->num_sectors; i++) { + for (int i = 0; i < bank->num_sectors; i++) { bank->sectors[i].offset = i * FLASH_PAGE_SIZE(bluenrgx_info); bank->sectors[i].size = FLASH_PAGE_SIZE(bluenrgx_info); bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 0; } - bluenrgx_info->probed = 1; + bluenrgx_info->probed = true; bluenrgx_info->die_id = die_id; return ERROR_OK; From dadf46f618b9cb3baea8679a4f6364df66092aac Mon Sep 17 00:00:00 2001 From: iosabi Date: Thu, 9 Apr 2020 16:23:34 +0000 Subject: [PATCH 306/354] cortex_m: make bit fields in cortex_m unsigned. Expression like (0xffff << 16) evaluate to type int, which is not able to hold that value, producing a warning when compiling with -fsanitize=undefined. This patch makes most of the cortex_m constants unsigned using the BIT() macro or appending "ul" when possible to fix the undefined behavior warning. Signed-off-by: iosabi Change-Id: I7af194305ef612d7a32e74eaf9f11dd85fa87f32 Reviewed-on: http://openocd.zylin.com/5583 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Christopher Head Reviewed-by: Tomas Vanek --- src/target/cortex_m.c | 2 +- src/target/cortex_m.h | 61 ++++++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index bb14bc846..e540f8507 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -129,7 +129,7 @@ static int cortex_m_write_debug_halt_mask(struct target *target, struct armv7m_common *armv7m = &cortex_m->armv7m; /* mask off status bits */ - cortex_m->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off); + cortex_m->dcb_dhcsr &= ~((0xFFFFul << 16) | mask_off); /* create new register mask */ cortex_m->dcb_dhcsr |= DBGKEY | C_DEBUGEN | mask_on; diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 505a09b68..a767f93c5 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -26,6 +26,7 @@ #define OPENOCD_TARGET_CORTEX_M_H #include "armv7m.h" +#include "helper/bits.h" #define CORTEX_M_COMMON_MAGIC 0x1A451A45 @@ -50,7 +51,7 @@ #define DCB_DCRDR 0xE000EDF8 #define DCB_DEMCR 0xE000EDFC -#define DCRSR_WnR (1 << 16) +#define DCRSR_WnR BIT(16) #define DWT_CTRL 0xE0001000 #define DWT_CYCCNT 0xE0001004 @@ -90,28 +91,28 @@ #define TPIU_ACPR_MAX_SWOSCALER 0x1fff /* DCB_DHCSR bit and field definitions */ -#define DBGKEY (0xA05F << 16) -#define C_DEBUGEN (1 << 0) -#define C_HALT (1 << 1) -#define C_STEP (1 << 2) -#define C_MASKINTS (1 << 3) -#define S_REGRDY (1 << 16) -#define S_HALT (1 << 17) -#define S_SLEEP (1 << 18) -#define S_LOCKUP (1 << 19) -#define S_RETIRE_ST (1 << 24) -#define S_RESET_ST (1 << 25) +#define DBGKEY (0xA05Ful << 16) +#define C_DEBUGEN BIT(0) +#define C_HALT BIT(1) +#define C_STEP BIT(2) +#define C_MASKINTS BIT(3) +#define S_REGRDY BIT(16) +#define S_HALT BIT(17) +#define S_SLEEP BIT(18) +#define S_LOCKUP BIT(19) +#define S_RETIRE_ST BIT(24) +#define S_RESET_ST BIT(25) /* DCB_DEMCR bit and field definitions */ -#define TRCENA (1 << 24) -#define VC_HARDERR (1 << 10) -#define VC_INTERR (1 << 9) -#define VC_BUSERR (1 << 8) -#define VC_STATERR (1 << 7) -#define VC_CHKERR (1 << 6) -#define VC_NOCPERR (1 << 5) -#define VC_MMERR (1 << 4) -#define VC_CORERESET (1 << 0) +#define TRCENA BIT(24) +#define VC_HARDERR BIT(10) +#define VC_INTERR BIT(9) +#define VC_BUSERR BIT(8) +#define VC_STATERR BIT(7) +#define VC_CHKERR BIT(6) +#define VC_NOCPERR BIT(5) +#define VC_MMERR BIT(4) +#define VC_CORERESET BIT(0) #define NVIC_ICTR 0xE000E004 #define NVIC_ISE0 0xE000E100 @@ -128,12 +129,12 @@ #define NVIC_BFAR 0xE000ED38 /* NVIC_AIRCR bits */ -#define AIRCR_VECTKEY (0x5FA << 16) -#define AIRCR_SYSRESETREQ (1 << 2) -#define AIRCR_VECTCLRACTIVE (1 << 1) -#define AIRCR_VECTRESET (1 << 0) +#define AIRCR_VECTKEY (0x5FAul << 16) +#define AIRCR_SYSRESETREQ BIT(2) +#define AIRCR_VECTCLRACTIVE BIT(1) +#define AIRCR_VECTRESET BIT(0) /* NVIC_SHCSR bits */ -#define SHCSR_BUSFAULTENA (1 << 17) +#define SHCSR_BUSFAULTENA BIT(17) /* NVIC_DFSR bits */ #define DFSR_HALTED 1 #define DFSR_BKPT 2 @@ -143,10 +144,10 @@ #define FPCR_CODE 0 #define FPCR_LITERAL 1 -#define FPCR_REPLACE_REMAP (0 << 30) -#define FPCR_REPLACE_BKPT_LOW (1 << 30) -#define FPCR_REPLACE_BKPT_HIGH (2 << 30) -#define FPCR_REPLACE_BKPT_BOTH (3 << 30) +#define FPCR_REPLACE_REMAP (0ul << 30) +#define FPCR_REPLACE_BKPT_LOW (1ul << 30) +#define FPCR_REPLACE_BKPT_HIGH (2ul << 30) +#define FPCR_REPLACE_BKPT_BOTH (3ul << 30) struct cortex_m_fp_comparator { bool used; From 11c5efd2ecd8df002567e272b874f2e6b821d9cd Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 12 May 2020 16:21:13 +0200 Subject: [PATCH 307/354] target/arc: fix build with clang Commit da41bce3aee9 ("target/arc: introduce breakpoint functionality") introduces a mismatch between the format string and one int constant. Change the format string to match the int constant. Change-Id: I0d59552205551b90e165c0a2e3fef247ad0c7701 Signed-off-by: Antonio Borneo Fixes: da41bce3aee9 ("target/arc: introduce breakpoint functionality") Reviewed-on: http://openocd.zylin.com/5655 Tested-by: jenkins Reviewed-by: Evgeniy Didin Reviewed-by: Tarek BOCHKATI --- src/target/arc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/arc.c b/src/target/arc.c index bf744962a..6cf0ec7af 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -1445,7 +1445,7 @@ static int arc_unset_breakpoint(struct target *target, } else { LOG_WARNING("Software breakpoint @0x%" TARGET_PRIxADDR " has been overwritten outside of debugger. " - "Expected: 0x%04" PRIx16 ", got: 0x%04" PRIx16, + "Expected: 0x%04x, got: 0x%04" PRIx16, breakpoint->address, ARC_SDBBP_16, current_instr); } } else { From e41c0f4906e46d1076ce62a0da5518aa1ca280b8 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Tue, 30 Jan 2018 12:17:33 +0300 Subject: [PATCH 308/354] flash: nor: jtagspi: make read_status report errors This is a follow-up to 3c9bd7c6f30a34e3930e44dd2e8ce5f5a877b4eb. Change-Id: If430f7fcfbba084d9cd74b32344ad43508a96a77 Signed-off-by: Paul Fertser Reviewed-on: http://openocd.zylin.com/4383 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tomas Vanek --- src/flash/nor/jtagspi.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c index f6e311ab8..73b1c7a26 100644 --- a/src/flash/nor/jtagspi.c +++ b/src/flash/nor/jtagspi.c @@ -228,13 +228,16 @@ static int jtagspi_probe(struct flash_bank *bank) return ERROR_OK; } -static void jtagspi_read_status(struct flash_bank *bank, uint32_t *status) +static int jtagspi_read_status(struct flash_bank *bank, uint32_t *status) { uint8_t buf; - if (jtagspi_cmd(bank, SPIFLASH_READ_STATUS, NULL, &buf, -8) == ERROR_OK) { + int err = jtagspi_cmd(bank, SPIFLASH_READ_STATUS, NULL, &buf, -8); + if (err == ERROR_OK) { *status = buf; /* LOG_DEBUG("status=0x%08" PRIx32, *status); */ } + + return err; } static int jtagspi_wait(struct flash_bank *bank, int timeout_ms) @@ -245,7 +248,11 @@ static int jtagspi_wait(struct flash_bank *bank, int timeout_ms) do { dt = timeval_ms() - t0; - jtagspi_read_status(bank, &status); + + int retval = jtagspi_read_status(bank, &status); + if (retval != ERROR_OK) + return retval; + if ((status & SPIFLASH_BSY_BIT) == 0) { LOG_DEBUG("waited %" PRId64 " ms", dt); return ERROR_OK; @@ -262,7 +269,11 @@ static int jtagspi_write_enable(struct flash_bank *bank) uint32_t status; jtagspi_cmd(bank, SPIFLASH_WRITE_ENABLE, NULL, NULL, 0); - jtagspi_read_status(bank, &status); + + int retval = jtagspi_read_status(bank, &status); + if (retval != ERROR_OK) + return retval; + if ((status & SPIFLASH_WE_BIT) == 0) { LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32, status); return ERROR_FAIL; From 0637047c6549e1e30f38e4084e516a4e6d67a167 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Wed, 13 May 2020 15:03:14 -0700 Subject: [PATCH 309/354] contrib: Add HiFive1 to udev rules Change-Id: I4ba9219e1c673d650931f8f9426d554de8322abf Signed-off-by: Alistair Francis Reviewed-on: http://openocd.zylin.com/5678 Tested-by: jenkins Reviewed-by: Antonio Borneo --- contrib/60-openocd.rules | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/60-openocd.rules b/contrib/60-openocd.rules index 990412752..617346d1c 100644 --- a/contrib/60-openocd.rules +++ b/contrib/60-openocd.rules @@ -109,6 +109,8 @@ ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1015", MODE="660", GROUP="plugdev", ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1016", MODE="660", GROUP="plugdev", TAG+="uaccess" ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1017", MODE="660", GROUP="plugdev", TAG+="uaccess" ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1018", MODE="660", GROUP="plugdev", TAG+="uaccess" +ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1051", MODE="660", GROUP="plugdev", TAG+="uaccess" +ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1061", MODE="660", GROUP="plugdev", TAG+="uaccess" # Raisonance RLink ATTRS{idVendor}=="138e", ATTRS{idProduct}=="9000", MODE="660", GROUP="plugdev", TAG+="uaccess" From ec30634c13e9a311d597b8860a4671d91cfb34a6 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Wed, 6 Mar 2019 12:16:53 +0100 Subject: [PATCH 310/354] rtos/ChibiOS: Fix some coding styles Change-Id: I2648479df1a2dd95f8a57868c4ed4259e0fbbe11 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/4989 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/rtos/Makefile.am | 2 +- src/rtos/{ChibiOS.c => chibios.c} | 118 +++++++++++++++--------------- src/rtos/rtos.c | 4 +- 3 files changed, 62 insertions(+), 62 deletions(-) rename src/rtos/{ChibiOS.c => chibios.c} (83%) diff --git a/src/rtos/Makefile.am b/src/rtos/Makefile.am index 38adb6e92..6a2fc1223 100644 --- a/src/rtos/Makefile.am +++ b/src/rtos/Makefile.am @@ -11,7 +11,7 @@ noinst_LTLIBRARIES += %D%/librtos.la %D%/ThreadX.c \ %D%/eCos.c \ %D%/linux.c \ - %D%/ChibiOS.c \ + %D%/chibios.c \ %D%/chromium-ec.c \ %D%/embKernel.c \ %D%/mqx.c \ diff --git a/src/rtos/ChibiOS.c b/src/rtos/chibios.c similarity index 83% rename from src/rtos/ChibiOS.c rename to src/rtos/chibios.c index 08b234fa9..4d2b1b2d7 100644 --- a/src/rtos/ChibiOS.c +++ b/src/rtos/chibios.c @@ -39,7 +39,7 @@ * * @details Definition copied from os/kernel/include/chregistry.h of ChibiOS/RT. */ -struct ChibiOS_chdebug { +struct chibios_chdebug { char ch_identifier[4]; /**< @brief Always set to "main". */ uint8_t ch_zero; /**< @brief Must be zero. */ uint8_t ch_size; /**< @brief Size of this structure. */ @@ -69,26 +69,26 @@ struct ChibiOS_chdebug { /** * @brief ChibiOS thread states. */ -static const char * const ChibiOS_thread_states[] = { "READY", "CURRENT", +static const char * const chibios_thread_states[] = { "READY", "CURRENT", "WTSTART", "SUSPENDED", "QUEUED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING", "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "FINAL" }; -#define CHIBIOS_NUM_STATES (sizeof(ChibiOS_thread_states)/sizeof(char *)) +#define CHIBIOS_NUM_STATES (sizeof(chibios_thread_states)/sizeof(char *)) /* Maximum ChibiOS thread name. There is no real limit set by ChibiOS but 64 * chars ought to be enough. */ #define CHIBIOS_THREAD_NAME_STR_SIZE (64) -struct ChibiOS_params { +struct chibios_params { const char *target_name; - struct ChibiOS_chdebug *signature; + struct chibios_chdebug *signature; const struct rtos_register_stacking *stacking_info; }; -static struct ChibiOS_params ChibiOS_params_list[] = { +static struct chibios_params chibios_params_list[] = { { "cortex_m", /* target_name */ 0, @@ -100,23 +100,23 @@ static struct ChibiOS_params ChibiOS_params_list[] = { NULL, /* stacking_info */ } }; -#define CHIBIOS_NUM_PARAMS ((int)(sizeof(ChibiOS_params_list)/sizeof(struct ChibiOS_params))) +#define CHIBIOS_NUM_PARAMS ((int)(sizeof(chibios_params_list)/sizeof(struct chibios_params))) -static bool ChibiOS_detect_rtos(struct target *target); -static int ChibiOS_create(struct target *target); -static int ChibiOS_update_threads(struct rtos *rtos); -static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, +static bool chibios_detect_rtos(struct target *target); +static int chibios_create(struct target *target); +static int chibios_update_threads(struct rtos *rtos); +static int chibios_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs); -static int ChibiOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); +static int chibios_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]); -struct rtos_type ChibiOS_rtos = { - .name = "ChibiOS", +struct rtos_type chibios_rtos = { + .name = "chibios", - .detect_rtos = ChibiOS_detect_rtos, - .create = ChibiOS_create, - .update_threads = ChibiOS_update_threads, - .get_thread_reg_list = ChibiOS_get_thread_reg_list, - .get_symbol_list_to_lookup = ChibiOS_get_symbol_list_to_lookup, + .detect_rtos = chibios_detect_rtos, + .create = chibios_create, + .update_threads = chibios_update_threads, + .get_thread_reg_list = chibios_get_thread_reg_list, + .get_symbol_list_to_lookup = chibios_get_symbol_list_to_lookup, }; @@ -125,13 +125,13 @@ struct rtos_type ChibiOS_rtos = { * use whatever is available. */ -enum ChibiOS_symbol_values { - ChibiOS_VAL_rlist = 0, - ChibiOS_VAL_ch = 1, - ChibiOS_VAL_ch_debug = 2 +enum chibios_symbol_values { + CHIBIOS_VAL_RLIST = 0, + CHIBIOS_VAL_CH = 1, + CHIBIOS_VAL_CH_DEBUG = 2 }; -static symbol_table_elem_t ChibiOS_symbol_list[] = { +static symbol_table_elem_t chibios_symbol_list[] = { { "rlist", 0, true}, /* Thread ready list */ { "ch", 0, true}, /* System data structure */ { "ch_debug", 0, false}, /* Memory Signature containing offsets of fields in rlist */ @@ -141,13 +141,13 @@ static symbol_table_elem_t ChibiOS_symbol_list[] = { /* Offset of the rlist structure within the system data structure (ch) */ #define CH_RLIST_OFFSET 0x00 -static int ChibiOS_update_memory_signature(struct rtos *rtos) +static int chibios_update_memory_signature(struct rtos *rtos) { int retval; - struct ChibiOS_params *param; - struct ChibiOS_chdebug *signature; + struct chibios_params *param; + struct chibios_chdebug *signature; - param = (struct ChibiOS_params *) rtos->rtos_specific_params; + param = (struct chibios_params *) rtos->rtos_specific_params; /* Free existing memory description.*/ if (param->signature) { @@ -162,7 +162,7 @@ static int ChibiOS_update_memory_signature(struct rtos *rtos) } retval = target_read_buffer(rtos->target, - rtos->symbols[ChibiOS_VAL_ch_debug].address, + rtos->symbols[CHIBIOS_VAL_CH_DEBUG].address, sizeof(*signature), (uint8_t *) signature); if (retval != ERROR_OK) { @@ -217,7 +217,7 @@ errfree: } -static int ChibiOS_update_stacking(struct rtos *rtos) +static int chibios_update_stacking(struct rtos *rtos) { /* Sometimes the stacking can not be determined only by looking at the * target name but only a runtime. @@ -234,15 +234,15 @@ static int ChibiOS_update_stacking(struct rtos *rtos) * - Since no threads are running during startup, the problem is solved * by delaying stacking detection until there are more threads * available than the current execution. In which case - * ChibiOS_get_thread_reg_list is called. + * chibios_get_thread_reg_list is called. */ int retval; if (!rtos->rtos_specific_params) return -1; - struct ChibiOS_params *param; - param = (struct ChibiOS_params *) rtos->rtos_specific_params; + struct chibios_params *param; + param = (struct chibios_params *) rtos->rtos_specific_params; /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4 */ struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target); @@ -274,10 +274,10 @@ static int ChibiOS_update_stacking(struct rtos *rtos) return -1; } -static int ChibiOS_update_threads(struct rtos *rtos) +static int chibios_update_threads(struct rtos *rtos) { int retval; - const struct ChibiOS_params *param; + const struct chibios_params *param; int tasks_found = 0; int rtos_valid = -1; @@ -289,10 +289,10 @@ static int ChibiOS_update_threads(struct rtos *rtos) return -3; } - param = (const struct ChibiOS_params *) rtos->rtos_specific_params; + param = (const struct chibios_params *) rtos->rtos_specific_params; /* Update the memory signature saved in the target memory */ if (!param->signature) { - retval = ChibiOS_update_memory_signature(rtos); + retval = chibios_update_memory_signature(rtos); if (retval != ERROR_OK) { LOG_ERROR("Reading the memory signature of ChibiOS/RT failed"); return retval; @@ -305,10 +305,10 @@ static int ChibiOS_update_threads(struct rtos *rtos) /* ChibiOS does not save the current thread count. We have to first * parse the double linked thread list to check for errors and the number of * threads. */ - const uint32_t rlist = rtos->symbols[ChibiOS_VAL_rlist].address ? - rtos->symbols[ChibiOS_VAL_rlist].address : - rtos->symbols[ChibiOS_VAL_ch].address + CH_RLIST_OFFSET /* ChibiOS3 */; - const struct ChibiOS_chdebug *signature = param->signature; + const uint32_t rlist = rtos->symbols[CHIBIOS_VAL_RLIST].address ? + rtos->symbols[CHIBIOS_VAL_RLIST].address : + rtos->symbols[CHIBIOS_VAL_CH].address + CH_RLIST_OFFSET /* ChibiOS3 */; + const struct chibios_chdebug *signature = param->signature; uint32_t current; uint32_t previous; uint32_t older; @@ -426,19 +426,19 @@ static int ChibiOS_update_threads(struct rtos *rtos) strcpy(curr_thrd_details->thread_name_str, tmp_str); /* State info */ - uint8_t threadState; + uint8_t thread_state; const char *state_desc; retval = target_read_u8(rtos->target, - current + signature->cf_off_state, &threadState); + current + signature->cf_off_state, &thread_state); if (retval != ERROR_OK) { LOG_ERROR("Error reading thread state from ChibiOS target"); return retval; } - if (threadState < CHIBIOS_NUM_STATES) - state_desc = ChibiOS_thread_states[threadState]; + if (thread_state < CHIBIOS_NUM_STATES) + state_desc = chibios_thread_states[thread_state]; else state_desc = "Unknown"; @@ -465,25 +465,25 @@ static int ChibiOS_update_threads(struct rtos *rtos) return 0; } -static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, +static int chibios_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs) { int retval; - const struct ChibiOS_params *param; + const struct chibios_params *param; uint32_t stack_ptr = 0; if ((rtos == NULL) || (thread_id == 0) || (rtos->rtos_specific_params == NULL)) return -1; - param = (const struct ChibiOS_params *) rtos->rtos_specific_params; + param = (const struct chibios_params *) rtos->rtos_specific_params; if (!param->signature) return -1; /* Update stacking if it can only be determined from runtime information */ if ((param->stacking_info == 0) && - (ChibiOS_update_stacking(rtos) != ERROR_OK)) { + (chibios_update_stacking(rtos) != ERROR_OK)) { LOG_ERROR("Failed to determine exact stacking for the target type %s", rtos->target->type->name); return -1; } @@ -499,24 +499,24 @@ static int ChibiOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, return rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, reg_list, num_regs); } -static int ChibiOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) +static int chibios_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]) { - *symbol_list = malloc(sizeof(ChibiOS_symbol_list)); + *symbol_list = malloc(sizeof(chibios_symbol_list)); if (*symbol_list == NULL) return ERROR_FAIL; - memcpy(*symbol_list, ChibiOS_symbol_list, sizeof(ChibiOS_symbol_list)); + memcpy(*symbol_list, chibios_symbol_list, sizeof(chibios_symbol_list)); return 0; } -static bool ChibiOS_detect_rtos(struct target *target) +static bool chibios_detect_rtos(struct target *target) { if ((target->rtos->symbols != NULL) && - ((target->rtos->symbols[ChibiOS_VAL_rlist].address != 0) || - (target->rtos->symbols[ChibiOS_VAL_ch].address != 0))) { + ((target->rtos->symbols[CHIBIOS_VAL_RLIST].address != 0) || + (target->rtos->symbols[CHIBIOS_VAL_CH].address != 0))) { - if (target->rtos->symbols[ChibiOS_VAL_ch_debug].address == 0) { + if (target->rtos->symbols[CHIBIOS_VAL_CH_DEBUG].address == 0) { LOG_INFO("It looks like the target may be running ChibiOS " "without ch_debug."); return false; @@ -529,11 +529,11 @@ static bool ChibiOS_detect_rtos(struct target *target) return false; } -static int ChibiOS_create(struct target *target) +static int chibios_create(struct target *target) { int i = 0; while ((i < CHIBIOS_NUM_PARAMS) && - (0 != strcmp(ChibiOS_params_list[i].target_name, target->type->name))) { + (0 != strcmp(chibios_params_list[i].target_name, target->type->name))) { i++; } if (i >= CHIBIOS_NUM_PARAMS) { @@ -542,6 +542,6 @@ static int ChibiOS_create(struct target *target) return -1; } - target->rtos->rtos_specific_params = (void *) &ChibiOS_params_list[i]; + target->rtos->rtos_specific_params = (void *) &chibios_params_list[i]; return 0; } diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 549833f41..221234828 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -31,7 +31,7 @@ extern struct rtos_type FreeRTOS_rtos; extern struct rtos_type ThreadX_rtos; extern struct rtos_type eCos_rtos; extern struct rtos_type Linux_os; -extern struct rtos_type ChibiOS_rtos; +extern struct rtos_type chibios_rtos; extern struct rtos_type chromium_ec_rtos; extern struct rtos_type embKernel_rtos; extern struct rtos_type mqx_rtos; @@ -44,7 +44,7 @@ static struct rtos_type *rtos_types[] = { &FreeRTOS_rtos, &eCos_rtos, &Linux_os, - &ChibiOS_rtos, + &chibios_rtos, &chromium_ec_rtos, &embKernel_rtos, &mqx_rtos, From 9a5af06f821e2c61adbf2b5cac720ba8d608a014 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Sun, 17 May 2020 08:17:25 +0200 Subject: [PATCH 311/354] flash/nor/jtagspi: propagate error from jtag_execute_queue() Change-Id: Ib985bdf3d60345a1e701f9cc98f89a47ff74d3e2 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/5684 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Antonio Borneo --- src/flash/nor/jtagspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flash/nor/jtagspi.c b/src/flash/nor/jtagspi.c index 73b1c7a26..d841579ff 100644 --- a/src/flash/nor/jtagspi.c +++ b/src/flash/nor/jtagspi.c @@ -153,12 +153,12 @@ static int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd, jtagspi_set_ir(bank); /* passing from an IR scan to SHIFT-DR clears BYPASS registers */ jtag_add_dr_scan(info->tap, n, fields, TAP_IDLE); - jtag_execute_queue(); + int retval = jtag_execute_queue(); if (is_read) flip_u8(data_buf, data, lenb); free(data_buf); - return ERROR_OK; + return retval; } static int jtagspi_probe(struct flash_bank *bank) From 763f2549ad4f9d3d59c472f79b4f9b37abb276ae Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Thu, 14 May 2020 15:49:15 -0500 Subject: [PATCH 312/354] nor/flash: Add keep_alive() during flash write handler Added keep_alive() call inside main flash write loop. Large files where causing a gdb timeout warning. Change-Id: I525dad2d644e248dd9ecf678e4d8e33c22eefdf2 Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5682 Reviewed-by: Antonio Borneo Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Tomas Vanek --- src/flash/nor/cc3220sf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/flash/nor/cc3220sf.c b/src/flash/nor/cc3220sf.c index afdb7f491..c8de7d002 100644 --- a/src/flash/nor/cc3220sf.c +++ b/src/flash/nor/cc3220sf.c @@ -363,6 +363,8 @@ static int cc3220sf_write(struct flash_bank *bank, const uint8_t *buffer, LOG_ERROR("cc3220sf: Flash operation failed"); break; } + + keep_alive(); } /* Do one word write for any final bytes less than a full word */ From ac870d80a9232fda1588c2784f157e6f8863f4b7 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Tue, 12 May 2020 21:00:18 +0100 Subject: [PATCH 313/354] arm_disassembler: fix typo 'ARM_UNKNOWN_INSTUCTION' to '.._INSTRUCTION' Change-Id: I3a3d566fe96fb1497cf8337389e993e0f728a64b Signed-off-by: Laurent LEMELE Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5657 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/arm_disassembler.c | 2 +- src/target/arm_disassembler.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/target/arm_disassembler.c b/src/target/arm_disassembler.c index 55aaddd0a..da8aee28b 100644 --- a/src/target/arm_disassembler.c +++ b/src/target/arm_disassembler.c @@ -2086,7 +2086,7 @@ static int evaluate_b_bl_blx_thumb(uint16_t opcode, break; /* BL/BLX prefix */ case 2: - instruction->type = ARM_UNKNOWN_INSTUCTION; + instruction->type = ARM_UNKNOWN_INSTRUCTION; mnemonic = "prefix"; target_address = offset << 12; break; diff --git a/src/target/arm_disassembler.h b/src/target/arm_disassembler.h index e9f4d44cb..486e903e3 100644 --- a/src/target/arm_disassembler.h +++ b/src/target/arm_disassembler.h @@ -20,7 +20,7 @@ #define OPENOCD_TARGET_ARM_DISASSEMBLER_H enum arm_instruction_type { - ARM_UNKNOWN_INSTUCTION, + ARM_UNKNOWN_INSTRUCTION, /* Branch instructions */ ARM_B, From 17789d3762aff931bc4bffd2c129100d952ccc84 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Mon, 4 May 2020 16:56:14 +0200 Subject: [PATCH 314/354] flash/nor/sh_qspi: Fix dead assignment Change-Id: I6a99076fea30062535e615244895698e51107441 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5645 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/flash/nor/sh_qspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/sh_qspi.c b/src/flash/nor/sh_qspi.c index 931b0b176..862e43aae 100644 --- a/src/flash/nor/sh_qspi.c +++ b/src/flash/nor/sh_qspi.c @@ -654,7 +654,7 @@ static int sh_qspi_read(struct flash_bank *bank, uint8_t *buffer, destroy_reg_param(®_params[2]); destroy_reg_param(®_params[3]); - return ERROR_OK; + return ret; } /* Return ID of flash device */ From 94dfa68647062ce71322f293a468bf5cdccf82be Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 18 Mar 2020 22:35:26 +0100 Subject: [PATCH 315/354] stlink: reduce use of hla specific enum hl_transports In the driver's code it's widely used the enum hl_transports for any check concerning the current transport, even for the non-hla transport dapdirect. The driver already provides a stlink specific enum stlink_mode that can be used in place of the hla one. Replace the hla enum with the stlink one allover the code. Introduce a hla specific wrapper stlink_usb_hl_open() to cope with the only API that requires the hla specific enum. The overall behaviour is not changed, with exception for a debug message in stlink_usb_open() than now prints the numeric value of stlink enum in place of the numeric value of the corresponding hla one. This change prepares the road for moving SWIM transport out of hla by removing any reference to the macro HL_TRANSPORT_SWIM from the stlink driver. Change-Id: Ieeea34f312245a94bfc1333087afdb8eb9f77139 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5526 Tested-by: jenkins --- src/jtag/drivers/stlink_usb.c | 102 +++++++++++++++++----------------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 03d3da7bb..aef02c563 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -95,6 +95,15 @@ enum stlink_jtag_api_version { STLINK_JTAG_API_V3, }; +enum stlink_mode { + STLINK_MODE_UNKNOWN = 0, + STLINK_MODE_DFU, + STLINK_MODE_MASS, + STLINK_MODE_DEBUG_JTAG, + STLINK_MODE_DEBUG_SWD, + STLINK_MODE_DEBUG_SWIM +}; + /** */ struct stlink_usb_version { /** */ @@ -132,7 +141,7 @@ struct stlink_usb_handle_s { /** */ uint32_t max_mem_packet; /** */ - enum hl_transports transport; + enum stlink_mode st_mode; /** */ struct stlink_usb_version version; /** */ @@ -292,16 +301,6 @@ struct stlink_usb_handle_s { #define STLINK_V3_MAX_FREQ_NB 10 -/** */ -enum stlink_mode { - STLINK_MODE_UNKNOWN = 0, - STLINK_MODE_DFU, - STLINK_MODE_MASS, - STLINK_MODE_DEBUG_JTAG, - STLINK_MODE_DEBUG_SWD, - STLINK_MODE_DEBUG_SWIM -}; - #define REQUEST_SENSE 0x03 #define REQUEST_SENSE_LENGTH 18 @@ -710,7 +709,7 @@ static int stlink_usb_error_check(void *handle) assert(handle != NULL); - if (h->transport == HL_TRANSPORT_SWIM) { + if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { switch (h->databuf[0]) { case STLINK_SWIM_ERR_OK: return ERROR_OK; @@ -819,13 +818,13 @@ static int stlink_cmd_allow_retry(void *handle, const uint8_t *buf, int size) struct stlink_usb_handle_s *h = handle; while (1) { - if ((h->transport != HL_TRANSPORT_SWIM) || !retries) { + if ((h->st_mode != STLINK_MODE_DEBUG_SWIM) || !retries) { res = stlink_usb_xfer_noerrcheck(handle, buf, size); if (res != ERROR_OK) return res; } - if (h->transport == HL_TRANSPORT_SWIM) { + if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { res = stlink_swim_status(handle); if (res != ERROR_OK) return res; @@ -1368,7 +1367,7 @@ static int stlink_usb_init_mode(void *handle, bool connect_under_reset, int init LOG_DEBUG("MODE: 0x%02X", mode); /* set selected mode */ - emode = stlink_get_mode(h->transport); + emode = h->st_mode; if (emode == STLINK_MODE_UNKNOWN) { LOG_ERROR("selected mode (transport) not supported"); @@ -1376,12 +1375,12 @@ static int stlink_usb_init_mode(void *handle, bool connect_under_reset, int init } /* set the speed before entering the mode, as the chip discovery phase should be done at this speed too */ - if (h->transport == HL_TRANSPORT_JTAG) { + if (emode == STLINK_MODE_DEBUG_JTAG) { if (h->version.flags & STLINK_F_HAS_JTAG_SET_FREQ) { stlink_dump_speed_map(stlink_khz_to_speed_map_jtag, ARRAY_SIZE(stlink_khz_to_speed_map_jtag)); stlink_speed(h, initial_interface_speed, false); } - } else if (h->transport == HL_TRANSPORT_SWD) { + } else if (emode == STLINK_MODE_DEBUG_SWD) { if (h->version.flags & STLINK_F_HAS_SWD_SET_FREQ) { stlink_dump_speed_map(stlink_khz_to_speed_map_swd, ARRAY_SIZE(stlink_khz_to_speed_map_swd)); stlink_speed(h, initial_interface_speed, false); @@ -1391,7 +1390,7 @@ static int stlink_usb_init_mode(void *handle, bool connect_under_reset, int init if (h->version.jtag_api == STLINK_JTAG_API_V3) { struct speed_map map[STLINK_V3_MAX_FREQ_NB]; - stlink_get_com_freq(h, (h->transport == HL_TRANSPORT_JTAG), map); + stlink_get_com_freq(h, (emode == STLINK_MODE_DEBUG_JTAG), map); stlink_dump_speed_map(map, ARRAY_SIZE(map)); stlink_speed(h, initial_interface_speed, false); } @@ -1632,7 +1631,7 @@ static int stlink_usb_idcode(void *handle, uint32_t *idcode) assert(handle != NULL); /* there is no swim read core id cmd */ - if (h->transport == HL_TRANSPORT_SWIM) { + if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { *idcode = 0; return ERROR_OK; } @@ -1763,8 +1762,8 @@ static enum target_state stlink_usb_state(void *handle) assert(handle != NULL); - if (h->transport == HL_TRANSPORT_SWIM) { - res = stlink_usb_mode_enter(handle, stlink_get_mode(h->transport)); + if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { + res = stlink_usb_mode_enter(handle, h->st_mode); if (res != ERROR_OK) return TARGET_UNKNOWN; @@ -1777,8 +1776,7 @@ static enum target_state stlink_usb_state(void *handle) if (h->reconnect_pending) { LOG_INFO("Previous state query failed, trying to reconnect"); - res = stlink_usb_mode_enter(handle, stlink_get_mode(h->transport)); - + res = stlink_usb_mode_enter(handle, h->st_mode); if (res != ERROR_OK) return TARGET_UNKNOWN; @@ -1818,7 +1816,7 @@ static int stlink_usb_assert_srst(void *handle, int srst) assert(handle != NULL); - if (h->transport == HL_TRANSPORT_SWIM) + if (h->st_mode == STLINK_MODE_DEBUG_SWIM) return stlink_swim_assert_reset(handle, srst); if (h->version.stlink == 1) @@ -1895,7 +1893,7 @@ static int stlink_usb_reset(void *handle) assert(handle != NULL); - if (h->transport == HL_TRANSPORT_SWIM) + if (h->st_mode == STLINK_MODE_DEBUG_SWIM) return stlink_swim_generate_rst(handle); stlink_usb_init_buffer(handle, h->rx_ep, 2); @@ -2325,7 +2323,7 @@ static int stlink_usb_read_mem(void *handle, uint32_t addr, uint32_t size, if (count < bytes_remaining) bytes_remaining = count; - if (h->transport == HL_TRANSPORT_SWIM) { + if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { retval = stlink_swim_readbytes(handle, addr, bytes_remaining, buffer); if (retval != ERROR_OK) return retval; @@ -2410,7 +2408,7 @@ static int stlink_usb_write_mem(void *handle, uint32_t addr, uint32_t size, if (count < bytes_remaining) bytes_remaining = count; - if (h->transport == HL_TRANSPORT_SWIM) { + if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { retval = stlink_swim_writebytes(handle, addr, bytes_remaining, buffer); if (retval != ERROR_OK) return retval; @@ -2674,16 +2672,16 @@ static int stlink_speed(void *handle, int khz, bool query) if (!handle) return khz; - switch (h->transport) { - case HL_TRANSPORT_SWIM: + switch (h->st_mode) { + case STLINK_MODE_DEBUG_SWIM: return stlink_speed_swim(handle, khz, query); - case HL_TRANSPORT_SWD: + case STLINK_MODE_DEBUG_SWD: if (h->version.jtag_api == STLINK_JTAG_API_V3) return stlink_speed_v3(handle, false, khz, query); else return stlink_speed_swd(handle, khz, query); break; - case HL_TRANSPORT_JTAG: + case STLINK_MODE_DEBUG_JTAG: if (h->version.jtag_api == STLINK_JTAG_API_V3) return stlink_speed_v3(handle, true, khz, query); else @@ -2824,7 +2822,7 @@ char *stlink_usb_get_alternate_serial(libusb_device_handle *device, } /** */ -static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) +static int stlink_usb_open(struct hl_interface_param_s *param, enum stlink_mode mode, void **fd) { int err, retry_count = 1; struct stlink_usb_handle_s *h; @@ -2838,11 +2836,11 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) return ERROR_FAIL; } - h->transport = param->transport; + h->st_mode = mode; for (unsigned i = 0; param->vid[i]; i++) { LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", - param->transport, param->vid[i], param->pid[i], + h->st_mode, param->vid[i], param->pid[i], param->serial ? param->serial : ""); } @@ -2942,16 +2940,16 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) /* check if mode is supported */ err = ERROR_OK; - switch (h->transport) { - case HL_TRANSPORT_SWD: + switch (h->st_mode) { + case STLINK_MODE_DEBUG_SWD: if (h->version.jtag_api == STLINK_JTAG_API_V1) err = ERROR_FAIL; /* fall-through */ - case HL_TRANSPORT_JTAG: + case STLINK_MODE_DEBUG_JTAG: if (h->version.jtag == 0) err = ERROR_FAIL; break; - case HL_TRANSPORT_SWIM: + case STLINK_MODE_DEBUG_SWIM: if (h->version.swim == 0) err = ERROR_FAIL; break; @@ -2973,7 +2971,7 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) goto error_open; } - if (h->transport == HL_TRANSPORT_SWIM) { + if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { err = stlink_swim_enter(h); if (err != ERROR_OK) { LOG_ERROR("stlink_swim_enter_failed (unable to connect to the target)"); @@ -3011,6 +3009,11 @@ error_open: return ERROR_FAIL; } +static int stlink_usb_hl_open(struct hl_interface_param_s *param, void **fd) +{ + return stlink_usb_open(param, stlink_get_mode(param->transport), fd); +} + int stlink_config_trace(void *handle, bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t port_size, unsigned int *trace_freq, unsigned int traceclkin_freq, @@ -3144,7 +3147,7 @@ static int stlink_write_dap_register(void *handle, unsigned short dap_port, /** */ struct hl_layout_api_s stlink_usb_layout_api = { /** */ - .open = stlink_usb_open, + .open = stlink_usb_hl_open, /** */ .close = stlink_usb_close, /** */ @@ -3259,7 +3262,6 @@ static int stlink_dap_closeall_ap(void) static int stlink_dap_reinit_interface(void) { int retval; - enum stlink_mode mode; /* * On JTAG only, it should be enough to call stlink_usb_reset(). But on @@ -3269,13 +3271,12 @@ static int stlink_dap_reinit_interface(void) * select the mode again. */ - mode = stlink_get_mode(stlink_dap_param.transport); if (!stlink_dap_handle->reconnect_pending) { stlink_dap_handle->reconnect_pending = true; - stlink_usb_mode_leave(stlink_dap_handle, mode); + stlink_usb_mode_leave(stlink_dap_handle, stlink_dap_handle->st_mode); } - retval = stlink_usb_mode_enter(stlink_dap_handle, mode); + retval = stlink_usb_mode_enter(stlink_dap_handle, stlink_dap_handle->st_mode); if (retval != ERROR_OK) return retval; @@ -3322,7 +3323,7 @@ static int stlink_dap_op_connect(struct adiv5_dap *dap) retval = stlink_usb_idcode(stlink_dap_handle, &idcode); if (retval == ERROR_OK) LOG_INFO("%s %#8.8" PRIx32, - (stlink_dap_handle->transport == HL_TRANSPORT_JTAG) ? "JTAG IDCODE" : "SWD DPIDR", + (stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG) ? "JTAG IDCODE" : "SWD DPIDR", idcode); else dap->do_reconnect = true; @@ -3371,7 +3372,7 @@ static int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned reg, data = data ? : &dummy; if (stlink_dap_handle->version.flags & STLINK_F_QUIRK_JTAG_DP_READ - && stlink_dap_handle->transport == HL_TRANSPORT_JTAG) { + && stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG) { /* Quirk required in JTAG. Read RDBUFF to get the data */ retval = stlink_read_dap_register(stlink_dap_handle, STLINK_DEBUG_PORT_ACCESS, reg, &dummy); @@ -3507,7 +3508,7 @@ static int stlink_dap_op_run(struct adiv5_dap *dap) } if (ctrlstat & SSTICKYERR) { - if (stlink_dap_param.transport == HL_TRANSPORT_JTAG) + if (stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG) retval = stlink_dap_op_queue_dp_write(dap, DP_CTRL_STAT, ctrlstat & (dap->dp_ctrl_stat | SSTICKYERR)); else @@ -3635,6 +3636,7 @@ static const struct command_registration stlink_dap_command_handlers[] = { static int stlink_dap_init(void) { enum reset_types jtag_reset_config = jtag_get_reset_config(); + enum stlink_mode mode; int retval; LOG_DEBUG("stlink_dap_init()"); @@ -3647,15 +3649,15 @@ static int stlink_dap_init(void) } if (transport_is_dapdirect_swd()) - stlink_dap_param.transport = HL_TRANSPORT_SWD; + mode = STLINK_MODE_DEBUG_SWD; else if (transport_is_dapdirect_jtag()) - stlink_dap_param.transport = HL_TRANSPORT_JTAG; + mode = STLINK_MODE_DEBUG_JTAG; else { LOG_ERROR("Unsupported transport"); return ERROR_FAIL; } - retval = stlink_usb_open(&stlink_dap_param, (void **)&stlink_dap_handle); + retval = stlink_usb_open(&stlink_dap_param, mode, (void **)&stlink_dap_handle); if (retval != ERROR_OK) return retval; From 93c4c0fcbec1ebcb2ce19b37c39b63f10a91b9e8 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 26 Jan 2020 16:30:14 +0100 Subject: [PATCH 316/354] adapter: expose HLA interface in struct adapter_driver The transition of STM8/SWIM out of HLA will require a new struct swim_ops in struct adapter_driver. To simplify the development, make the HLA interface temporarily accessible through the struct adapter_driver. This commit will be reverted after the swim rework. Change-Id: I1e4f370cf64641164d7bcaa22f75ac58c9240052 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5527 Tested-by: jenkins --- src/jtag/hla/hla_interface.c | 3 +++ src/jtag/interface.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index 6d5cdc5e7..064c268e4 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -361,4 +361,7 @@ struct adapter_driver hl_adapter_driver = { .poll_trace = &hl_interface_poll_trace, /* no ops for HLA, targets hla_target and stm8 intercept them all */ + + /* FIXME: helper to simplify transition of HLA drivers. To be removed */ + .hla_if = &hl_if, }; diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 39d2d9d88..91291dbd1 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -37,6 +37,9 @@ */ +/* FIXME: prototype to simplify transition of HLA drivers. To be removed */ +struct hl_interface_s; + /** implementation of wrapper function tap_set_state() */ void tap_set_state_impl(tap_state_t new_state); @@ -359,6 +362,9 @@ struct adapter_driver { /* DAP APIs over SWD transport */ const struct dap_ops *dap_swd_ops; + + /* FIXME: helper to simplify transition of HLA drivers. To be removed */ + struct hl_interface_s *hla_if; }; extern const char * const jtag_only[]; From ac18e960ce79f06b22e71a17415be0feb741a482 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 26 Jan 2020 17:00:55 +0100 Subject: [PATCH 317/354] swim: abstract the transport in stm8 target SWIM is implemented by (ab)using the HLA API. This was acceptable when OpenOCD code did not provided a clear separation between transports and related APIs. Still today SWIM in OpenOCD is only supported by STLink, so the decision to re-use the HLA API was the simpler way to implement it. After commit efd1d642220a ("adapter: switch from struct jtag_interface to adapter_driver") the transports API are better split and SWIM can be implemented as a separate set of API. This would open the possibility to extend OpenOCD for other adapters that provide SWIM, e.g. versaloon, or through SPI emulation [1]. Introduce a new set of files swim.[ch] to handle the SWIM API. Beside the API that almost match the transport low-level data communication (system_reset, read_mem, write_mem), add a further API reconnect. Today, inside HLA STLink code, the reconnect is implemented by hacking the HLA API state(). Please notice that due to this hack the return type is incorrect; stlink_usb_state() returns ERROR_OK in SWIM mode, while its return type is enum target_state. Ignore the type mismatch and still call the HLA API state in the new SWIM API reconnect. Further commit will fix it. [1] http://kuku.eu.org/?projects/stm8spi/stm8spi Change-Id: I52018e1e2200cbd41af8e5031f7b35dc761b61d6 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5528 Tested-by: jenkins --- src/jtag/Makefile.am | 2 ++ src/jtag/swim.c | 51 ++++++++++++++++++++++++++++++++ src/jtag/swim.h | 65 +++++++++++++++++++++++++++++++++++++++++ src/target/stm8.c | 69 ++++++++++---------------------------------- 4 files changed, 134 insertions(+), 53 deletions(-) create mode 100644 src/jtag/swim.c create mode 100644 src/jtag/swim.h diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am index a76486399..b82914bcb 100644 --- a/src/jtag/Makefile.am +++ b/src/jtag/Makefile.am @@ -56,6 +56,7 @@ endif %D%/interface.c \ %D%/interfaces.c \ %D%/tcl.c \ + %D%/swim.c \ %D%/commands.h \ %D%/driver.h \ %D%/interface.h \ @@ -65,6 +66,7 @@ endif %D%/minidriver/minidriver_imp.h \ %D%/minidummy/jtag_minidriver.h \ %D%/swd.h \ + %D%/swim.h \ %D%/tcl.h \ $(JTAG_SRCS) diff --git a/src/jtag/swim.c b/src/jtag/swim.c new file mode 100644 index 000000000..965018c27 --- /dev/null +++ b/src/jtag/swim.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * Copyright (C) 2020 by Antonio Borneo hla_if); + + return adapter_driver->hla_if->layout->api->reset(adapter_driver->hla_if->handle); +} + +int swim_read_mem(uint32_t addr, uint32_t size, uint32_t count, + uint8_t *buffer) +{ + assert(adapter_driver->hla_if); + + return adapter_driver->hla_if->layout->api->read_mem(adapter_driver->hla_if->handle, addr, size, count, buffer); +} + +int swim_write_mem(uint32_t addr, uint32_t size, uint32_t count, + const uint8_t *buffer) +{ + assert(adapter_driver->hla_if); + + return adapter_driver->hla_if->layout->api->write_mem(adapter_driver->hla_if->handle, addr, size, count, buffer); +} + +int swim_reconnect(void) +{ + assert(adapter_driver->hla_if); + + return adapter_driver->hla_if->layout->api->state(adapter_driver->hla_if->handle); +} diff --git a/src/jtag/swim.h b/src/jtag/swim.h new file mode 100644 index 000000000..d0ae18eab --- /dev/null +++ b/src/jtag/swim.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * Copyright (C) 2020 by Antonio Borneo tap->priv; -} - static int stm8_adapter_read_memory(struct target *target, uint32_t addr, int size, int count, void *buf) { - int ret; - struct hl_interface_s *adapter = target_to_adapter(target); - - ret = adapter->layout->api->read_mem(adapter->handle, - addr, size, count, buf); - if (ret != ERROR_OK) - return ret; - return ERROR_OK; + return swim_read_mem(addr, size, count, buf); } static int stm8_adapter_write_memory(struct target *target, uint32_t addr, int size, int count, const void *buf) { - int ret; - struct hl_interface_s *adapter = target_to_adapter(target); - - ret = adapter->layout->api->write_mem(adapter->handle, - addr, size, count, buf); - if (ret != ERROR_OK) - return ret; - return ERROR_OK; + return swim_write_mem(addr, size, count, buf); } static int stm8_write_u8(struct target *target, uint32_t addr, uint8_t val) { - int ret; uint8_t buf[1]; - struct hl_interface_s *adapter = target_to_adapter(target); buf[0] = val; - ret = adapter->layout->api->write_mem(adapter->handle, addr, 1, 1, buf); - if (ret != ERROR_OK) - return ret; - return ERROR_OK; + return swim_write_mem(addr, 1, 1, buf); } static int stm8_read_u8(struct target *target, uint32_t addr, uint8_t *val) { - int ret; - struct hl_interface_s *adapter = target_to_adapter(target); - - ret = adapter->layout->api->read_mem(adapter->handle, addr, 1, 1, val); - if (ret != ERROR_OK) - return ret; - return ERROR_OK; -} - -static int stm8_set_speed(struct target *target, int speed) -{ - struct hl_interface_s *adapter = target_to_adapter(target); - adapter->layout->api->speed(adapter->handle, speed, 0); - return ERROR_OK; + return swim_read_mem(addr, 1, 1, val); } /* @@ -924,7 +885,6 @@ static int stm8_halt(struct target *target) static int stm8_reset_assert(struct target *target) { int res = ERROR_OK; - struct hl_interface_s *adapter = target_to_adapter(target); struct stm8_common *stm8 = target_to_stm8(target); bool use_srst_fallback = true; @@ -942,7 +902,7 @@ static int stm8_reset_assert(struct target *target) if (use_srst_fallback) { LOG_DEBUG("Hardware srst not supported, falling back to swim reset"); - res = adapter->layout->api->reset(adapter->handle); + res = swim_system_reset(); if (res != ERROR_OK) return res; } @@ -1696,7 +1656,7 @@ static int stm8_examine(struct target *target) uint8_t csr1, csr2; /* get pointers to arch-specific information */ struct stm8_common *stm8 = target_to_stm8(target); - struct hl_interface_s *adapter = target_to_adapter(target); + enum reset_types jtag_reset_config = jtag_get_reset_config(); if (!target_was_examined(target)) { if (!stm8->swim_configured) { @@ -1710,20 +1670,23 @@ static int stm8_examine(struct target *target) retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM + HS); if (retval != ERROR_OK) return retval; - retval = stm8_set_speed(target, 1); - if (retval == ERROR_OK) - stm8->swim_configured = true; + jtag_config_khz(1); + stm8->swim_configured = true; /* Now is the time to deassert reset if connect_under_reset. Releasing reset line will cause the option bytes to load. The core will still be stalled. */ - if (adapter->param.connect_under_reset) - stm8_reset_deassert(target); + if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { + if (jtag_reset_config & RESET_SRST_NO_GATING) + stm8_reset_deassert(target); + else + LOG_WARNING("\'srst_nogate\' reset_config option is required"); + } } else { LOG_INFO("trying to reconnect"); - retval = adapter->layout->api->state(adapter->handle); + retval = swim_reconnect(); if (retval != ERROR_OK) { LOG_ERROR("reconnect failed"); return ERROR_FAIL; From ac05f929edffd6f1a4491d0b1e6cc95122ec6eb1 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 4 Feb 2020 11:07:01 +0100 Subject: [PATCH 318/354] swim: fix adapter speed handling SWIM transport only supports two adapter speeds: - "low speed" equal to 363 kHz (8 MHz / 22) - "high speed" equal to 800 kHz (8 MHz / 10) Replace the previous convention that use "0" or "1" for "low" or "high" speed with the effective speed in kHz. Rework the implementation of stlink_speed_swim(). Set low speed in the stm8 config files, because only low speed is permitted at debug connection; the previous code ignores the initial value. Change-Id: I2484c9419a2c554c59eb6b9216339393ab0b54f3 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5529 Tested-by: jenkins --- src/jtag/drivers/stlink_usb.c | 16 ++++++++++------ src/jtag/swim.h | 3 +++ src/target/stm8.c | 2 +- tcl/target/stm8l.cfg | 4 ++-- tcl/target/stm8s.cfg | 4 ++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index aef02c563..485a95c6b 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -2478,17 +2479,20 @@ static int stlink_usb_override_target(const char *targetname) static int stlink_speed_swim(void *handle, int khz, bool query) { + int retval; + /* - we dont care what the khz rate is we only have low and high speed... before changing speed the SWIM_CSR HS bit must be updated */ - if (khz == 0) - stlink_swim_speed(handle, 0); - else - stlink_swim_speed(handle, 1); - return khz; + if (!query) { + retval = stlink_swim_speed(handle, (khz < SWIM_FREQ_HIGH) ? 0 : 1); + if (retval != ERROR_OK) + LOG_ERROR("Unable to set adapter speed"); + } + + return (khz < SWIM_FREQ_HIGH) ? SWIM_FREQ_LOW : SWIM_FREQ_HIGH; } static int stlink_match_speed_map(const struct speed_map *map, unsigned int map_size, int khz, bool query) diff --git a/src/jtag/swim.h b/src/jtag/swim.h index d0ae18eab..186e0cc71 100644 --- a/src/jtag/swim.h +++ b/src/jtag/swim.h @@ -13,6 +13,9 @@ #ifndef OPENOCD_JTAG_SWIM_H #define OPENOCD_JTAG_SWIM_H +#define SWIM_FREQ_LOW 363 +#define SWIM_FREQ_HIGH 800 + struct swim_driver { /** * Send SRST (system reset) command to target. diff --git a/src/target/stm8.c b/src/target/stm8.c index ad05b54f9..c06e0fae7 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -1670,7 +1670,7 @@ static int stm8_examine(struct target *target) retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM + HS); if (retval != ERROR_OK) return retval; - jtag_config_khz(1); + jtag_config_khz(SWIM_FREQ_HIGH); stm8->swim_configured = true; /* Now is the time to deassert reset if connect_under_reset. diff --git a/tcl/target/stm8l.cfg b/tcl/target/stm8l.cfg index 386f371ea..f3c94280a 100644 --- a/tcl/target/stm8l.cfg +++ b/tcl/target/stm8l.cfg @@ -78,8 +78,8 @@ $_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocks # Set stm8l type $_TARGETNAME configure -enable_stm8l -# The khz rate does not apply here, only slow <0> and fast <1> -adapter speed 1 +# Set low speed at debug entry +adapter speed 363 reset_config srst_only diff --git a/tcl/target/stm8s.cfg b/tcl/target/stm8s.cfg index 4768068e8..5d52aea12 100644 --- a/tcl/target/stm8s.cfg +++ b/tcl/target/stm8s.cfg @@ -75,8 +75,8 @@ $_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocks # Uncomment this line to enable interrupts while instruction step #$_TARGETNAME configure -enable_step_irq -# The khz rate does not apply here, only slow <0> and fast <1> -adapter speed 1 +# Set low speed at debug entry +adapter speed 363 reset_config srst_only From ffe6bc82201ff3dceea193af530738d868258b0b Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 27 Jan 2020 18:45:10 +0100 Subject: [PATCH 319/354] swim: add new transport Add SWIM and STM8 to documentation and update TODO file. Introduce transport "swim" and command "swim newtap". Switch in swim.c from HLA API to the new SWIM API. Implement in stlink driver the SWIM APIs as wrappers of existing HLA functions. Remove any SWIM related reference from HLA files. Update stm8 config files and stlink-dap interface config file. Change-Id: I2bb9f58d52900f6eb4df05f979f7ef11fd439c24 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5530 Tested-by: jenkins --- TODO | 3 +- doc/openocd.texi | 24 +++++++ src/jtag/core.c | 9 ++- src/jtag/drivers/stlink_usb.c | 39 +++++++++-- src/jtag/hla/hla_transport.c | 14 +--- src/jtag/hla/hla_transport.h | 1 - src/jtag/interface.h | 4 ++ src/jtag/swim.c | 124 +++++++++++++++++++++++++++++++--- src/transport/transport.h | 1 + tcl/interface/stlink-dap.cfg | 11 +-- tcl/target/stm8l.cfg | 4 +- tcl/target/stm8s.cfg | 4 +- 12 files changed, 197 insertions(+), 41 deletions(-) diff --git a/TODO b/TODO index c73d772e2..ebb6c9980 100644 --- a/TODO +++ b/TODO @@ -59,8 +59,7 @@ changes pending in gerrit. - tap_set_state(TAP_RESET) is already done in src/jtag/core.c. No need to replicate it in the drivers, apart in case the driver sets TRST independently -- separate SWIM from HLA and make it independent -- add .hla_ops and .swim_ops to "adapter" +- add .hla_ops to "adapter" - HLA is a API level (.hla_ops). Transport should simply be {jtag,swd}, not {hla_jtag,hla_swd}. diff --git a/doc/openocd.texi b/doc/openocd.texi index ef77993ec..1ddf09ffa 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -3304,6 +3304,24 @@ The Serial Peripheral Interface (SPI) is a general purpose transport which uses four wire signaling. Some processors use it as part of a solution for flash programming. +@anchor{swimtransport} +@subsection SWIM Transport +@cindex SWIM +@cindex Single Wire Interface Module +The Single Wire Interface Module (SWIM) is a low-pin-count debug protocol used +by the STMicroelectronics MCU family STM8 and documented in the +@uref{https://www.st.com/resource/en/user_manual/cd00173911.pdf, User Manual UM470}. + +SWIM does not support boundary scan testing nor multiple cores. + +The SWIM transport is selected with the command @command{transport select swim}. + +The concept of TAPs does not fit in the protocol since SWIM does not implement +a scan chain. Nevertheless, the current SW model of OpenOCD requires defining a +virtual SWIM TAP through the command @command{swim newtap basename tap_type}. +The TAP definition must precede the target definition command +@command{target create target_name stm8 -chain-position basename.tap_type}. + @anchor{jtagspeed} @section JTAG Speed JTAG clock setup is part of system setup. @@ -9831,6 +9849,12 @@ This command is similar to @command{arc jtag get-aux-reg} but is for core registers. @end deffn +@section STM8 Architecture +@uref{http://st.com/stm8/, STM8} is a 8-bit microcontroller platform from +STMicroelectronics, based on a proprietary 8-bit core architecture. + +OpenOCD supports debugging STM8 through the STMicroelectronics debug +protocol SWIM, @pxref{swimtransport,,SWIM}. @anchor{softwaredebugmessagesandtracing} @section Software Debug Messages and Tracing diff --git a/src/jtag/core.c b/src/jtag/core.c index d83f19503..1d424b2e4 100644 --- a/src/jtag/core.c +++ b/src/jtag/core.c @@ -2027,7 +2027,8 @@ int adapter_resets(int trst, int srst) jtag_execute_queue(); return ERROR_OK; } else if (transport_is_swd() || transport_is_hla() || - transport_is_dapdirect_swd() || transport_is_dapdirect_jtag()) { + transport_is_dapdirect_swd() || transport_is_dapdirect_jtag() || + transport_is_swim()) { if (trst == TRST_ASSERT) { LOG_ERROR("transport %s has no trst signal", get_current_transport()->name); @@ -2060,7 +2061,8 @@ int adapter_assert_reset(void) jtag_add_reset(0, 1); return ERROR_OK; } else if (transport_is_swd() || transport_is_hla() || - transport_is_dapdirect_jtag() || transport_is_dapdirect_swd()) + transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() || + transport_is_swim()) return adapter_system_reset(1); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", @@ -2076,7 +2078,8 @@ int adapter_deassert_reset(void) jtag_add_reset(0, 0); return ERROR_OK; } else if (transport_is_swd() || transport_is_hla() || - transport_is_dapdirect_jtag() || transport_is_dapdirect_swd()) + transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() || + transport_is_swim()) return adapter_system_reset(0); else if (get_current_transport() != NULL) LOG_ERROR("reset is not supported on %s", diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 485a95c6b..4c5081c9e 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -1288,8 +1288,6 @@ static enum stlink_mode stlink_get_mode(enum hl_transports t) return STLINK_MODE_DEBUG_SWD; case HL_TRANSPORT_JTAG: return STLINK_MODE_DEBUG_JTAG; - case HL_TRANSPORT_SWIM: - return STLINK_MODE_DEBUG_SWIM; default: return STLINK_MODE_UNKNOWN; } @@ -3546,6 +3544,28 @@ static void stlink_dap_op_quit(struct adiv5_dap *dap) LOG_ERROR("Error closing APs"); } +static int stlink_swim_op_srst(void) +{ + return stlink_usb_reset(stlink_dap_handle); +} + +static int stlink_swim_op_read_mem(uint32_t addr, uint32_t size, + uint32_t count, uint8_t *buffer) +{ + return stlink_usb_read_mem(stlink_dap_handle, addr, size, count, buffer); +} + +static int stlink_swim_op_write_mem(uint32_t addr, uint32_t size, + uint32_t count, const uint8_t *buffer) +{ + return stlink_usb_write_mem(stlink_dap_handle, addr, size, count, buffer); +} + +static int stlink_swim_op_reconnect(void) +{ + return stlink_usb_state(stlink_dap_handle); +} + static int stlink_dap_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t port_size, unsigned int *trace_freq, unsigned int traceclkin_freq, @@ -3656,6 +3676,8 @@ static int stlink_dap_init(void) mode = STLINK_MODE_DEBUG_SWD; else if (transport_is_dapdirect_jtag()) mode = STLINK_MODE_DEBUG_JTAG; + else if (transport_is_swim()) + mode = STLINK_MODE_DEBUG_SWIM; else { LOG_ERROR("Unsupported transport"); return ERROR_FAIL; @@ -3665,7 +3687,8 @@ static int stlink_dap_init(void) if (retval != ERROR_OK) return retval; - if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_DAP_REG)) { + if ((mode != STLINK_MODE_DEBUG_SWIM) && + !(stlink_dap_handle->version.flags & STLINK_F_HAS_DAP_REG)) { LOG_ERROR("ST-Link version does not support DAP direct transport"); return ERROR_FAIL; } @@ -3737,7 +3760,14 @@ static const struct dap_ops stlink_dap_ops = { .quit = stlink_dap_op_quit, /* optional */ }; -static const char *const stlink_dap_transport[] = { "dapdirect_jtag", "dapdirect_swd", NULL }; +static const struct swim_driver stlink_swim_ops = { + .srst = stlink_swim_op_srst, + .read_mem = stlink_swim_op_read_mem, + .write_mem = stlink_swim_op_write_mem, + .reconnect = stlink_swim_op_reconnect, +}; + +static const char *const stlink_dap_transport[] = { "dapdirect_jtag", "dapdirect_swd", "swim", NULL }; struct adapter_driver stlink_dap_adapter_driver = { .name = "st-link", @@ -3755,4 +3785,5 @@ struct adapter_driver stlink_dap_adapter_driver = { .dap_jtag_ops = &stlink_dap_ops, .dap_swd_ops = &stlink_dap_ops, + .swim_ops = &stlink_swim_ops, }; diff --git a/src/jtag/hla/hla_transport.c b/src/jtag/hla/hla_transport.c index ddacea36a..fbdddfd65 100644 --- a/src/jtag/hla/hla_transport.c +++ b/src/jtag/hla/hla_transport.c @@ -175,8 +175,6 @@ static int hl_transport_init(struct command_context *cmd_ctx) tr = HL_TRANSPORT_SWD; else if (strcmp(transport->name, "hla_jtag") == 0) tr = HL_TRANSPORT_JTAG; - else if (strcmp(transport->name, "stlink_swim") == 0) - tr = HL_TRANSPORT_SWIM; int retval = hl_interface_open(tr); @@ -218,26 +216,18 @@ static struct transport hl_jtag_transport = { .override_target = hl_interface_override_target, }; -static struct transport stlink_swim_transport = { - .name = "stlink_swim", - .select = hl_transport_select, - .init = hl_transport_init, -}; - -const char *hl_transports[] = { "hla_swd", "hla_jtag", "stlink_swim", NULL }; +const char *hl_transports[] = { "hla_swd", "hla_jtag", NULL }; static void hl_constructor(void) __attribute__ ((constructor)); static void hl_constructor(void) { transport_register(&hl_swd_transport); transport_register(&hl_jtag_transport); - transport_register(&stlink_swim_transport); } bool transport_is_hla(void) { struct transport *t; t = get_current_transport(); - return t == &hl_swd_transport || t == &hl_jtag_transport - || t == &stlink_swim_transport; + return t == &hl_swd_transport || t == &hl_jtag_transport; } diff --git a/src/jtag/hla/hla_transport.h b/src/jtag/hla/hla_transport.h index 07eb751e2..0e0bea25f 100644 --- a/src/jtag/hla/hla_transport.h +++ b/src/jtag/hla/hla_transport.h @@ -26,7 +26,6 @@ enum hl_transports { HL_TRANSPORT_UNKNOWN = 0, HL_TRANSPORT_SWD, HL_TRANSPORT_JTAG, - HL_TRANSPORT_SWIM }; #endif /* OPENOCD_JTAG_HLA_HLA_TRANSPORT_H */ diff --git a/src/jtag/interface.h b/src/jtag/interface.h index 91291dbd1..a471aa96d 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -26,6 +26,7 @@ #define OPENOCD_JTAG_INTERFACE_H #include +#include #include /* @file @@ -363,6 +364,9 @@ struct adapter_driver { /* DAP APIs over SWD transport */ const struct dap_ops *dap_swd_ops; + /* SWIM APIs */ + const struct swim_driver *swim_ops; + /* FIXME: helper to simplify transition of HLA drivers. To be removed */ struct hl_interface_s *hla_if; }; diff --git a/src/jtag/swim.c b/src/jtag/swim.c index 965018c27..936268b25 100644 --- a/src/jtag/swim.c +++ b/src/jtag/swim.c @@ -14,38 +14,140 @@ #include "interface.h" #include "swim.h" -#include "jtag/hla/hla_transport.h" -#include "jtag/hla/hla_interface.h" -#include "jtag/hla/hla_layout.h" +#include +#include extern struct adapter_driver *adapter_driver; int swim_system_reset(void) { - assert(adapter_driver->hla_if); + assert(adapter_driver->swim_ops); - return adapter_driver->hla_if->layout->api->reset(adapter_driver->hla_if->handle); + return adapter_driver->swim_ops->srst(); } int swim_read_mem(uint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer) { - assert(adapter_driver->hla_if); + assert(adapter_driver->swim_ops); - return adapter_driver->hla_if->layout->api->read_mem(adapter_driver->hla_if->handle, addr, size, count, buffer); + return adapter_driver->swim_ops->read_mem(addr, size, count, buffer); } int swim_write_mem(uint32_t addr, uint32_t size, uint32_t count, const uint8_t *buffer) { - assert(adapter_driver->hla_if); + assert(adapter_driver->swim_ops); - return adapter_driver->hla_if->layout->api->write_mem(adapter_driver->hla_if->handle, addr, size, count, buffer); + return adapter_driver->swim_ops->write_mem(addr, size, count, buffer); } int swim_reconnect(void) { - assert(adapter_driver->hla_if); + assert(adapter_driver->swim_ops); - return adapter_driver->hla_if->layout->api->state(adapter_driver->hla_if->handle); + return adapter_driver->swim_ops->reconnect(); +} + +COMMAND_HANDLER(handle_swim_newtap_command) +{ + struct jtag_tap *tap; + + /* + * only need "basename" and "tap_type", but for backward compatibility + * ignore extra parameters + */ + if (CMD_ARGC < 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + tap = calloc(1, sizeof(*tap)); + if (!tap) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } + + tap->chip = strdup(CMD_ARGV[0]); + tap->tapname = strdup(CMD_ARGV[1]); + tap->dotted_name = alloc_printf("%s.%s", CMD_ARGV[0], CMD_ARGV[1]); + if (!tap->chip || !tap->tapname || !tap->dotted_name) { + LOG_ERROR("Out of memory"); + free(tap->dotted_name); + free(tap->tapname); + free(tap->chip); + free(tap); + return ERROR_FAIL; + } + + LOG_DEBUG("Creating new SWIM \"tap\", Chip: %s, Tap: %s, Dotted: %s", + tap->chip, tap->tapname, tap->dotted_name); + + /* default is enabled-after-reset */ + tap->enabled = true; + + jtag_tap_init(tap); + return ERROR_OK; +} + +static const struct command_registration swim_transport_subcommand_handlers[] = { + { + .name = "newtap", + .handler = handle_swim_newtap_command, + .mode = COMMAND_CONFIG, + .help = "Create a new TAP instance named basename.tap_type, " + "and appends it to the scan chain.", + .usage = "basename tap_type", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration swim_transport_command_handlers[] = { + { + .name = "swim", + .mode = COMMAND_ANY, + .help = "perform swim adapter actions", + .usage = "", + .chain = swim_transport_subcommand_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + +static int swim_transport_select(struct command_context *cmd_ctx) +{ + LOG_DEBUG(__func__); + + return register_commands(cmd_ctx, NULL, swim_transport_command_handlers); +} + +static int swim_transport_init(struct command_context *cmd_ctx) +{ + enum reset_types jtag_reset_config = jtag_get_reset_config(); + + LOG_DEBUG(__func__); + + if (jtag_reset_config & RESET_CNCT_UNDER_SRST) { + if (jtag_reset_config & RESET_SRST_NO_GATING) + adapter_assert_reset(); + else + LOG_WARNING("\'srst_nogate\' reset_config option is required"); + } else + adapter_deassert_reset(); + + return ERROR_OK; +} + +static struct transport swim_transport = { + .name = "swim", + .select = swim_transport_select, + .init = swim_transport_init, +}; + +static void swim_constructor(void) __attribute__ ((constructor)); +static void swim_constructor(void) +{ + transport_register(&swim_transport); +} + +bool transport_is_swim(void) +{ + return get_current_transport() == &swim_transport; } diff --git a/src/transport/transport.h b/src/transport/transport.h index 4effca5d5..809564e78 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -98,6 +98,7 @@ bool transport_is_jtag(void); bool transport_is_swd(void); bool transport_is_dapdirect_jtag(void); bool transport_is_dapdirect_swd(void); +bool transport_is_swim(void); #if BUILD_HLADAPTER bool transport_is_hla(void); diff --git a/tcl/interface/stlink-dap.cfg b/tcl/interface/stlink-dap.cfg index 4576ad388..ac4de18f9 100644 --- a/tcl/interface/stlink-dap.cfg +++ b/tcl/interface/stlink-dap.cfg @@ -1,16 +1,19 @@ # -# STMicroelectronics ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit +# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit # debugger/programmer # -# This new interface driver creates a ST-Link wrapper for ARM-DAP -# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support this method +# This new interface driver creates a ST-Link wrapper for ARM-DAP named "dapdirect" +# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support "dapdirect" +# +# SWIM transport is natively supported # adapter driver st-link -st-link vid_pid 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 +st-link vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 # transport select dapdirect_jtag # transport select dapdirect_swd +# transport select swim # Optionally specify the serial number of usb device # e.g. diff --git a/tcl/target/stm8l.cfg b/tcl/target/stm8l.cfg index f3c94280a..782350f78 100644 --- a/tcl/target/stm8l.cfg +++ b/tcl/target/stm8l.cfg @@ -4,7 +4,7 @@ # stm8 devices support SWIM transports only. # -transport select stlink_swim +transport select swim if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME @@ -62,7 +62,7 @@ if { [info exists BLOCKSIZE] } { set _BLOCKSIZE 0x80 } -hla newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0 +swim newtap $_CHIPNAME cpu set _TARGETNAME $_CHIPNAME.cpu diff --git a/tcl/target/stm8s.cfg b/tcl/target/stm8s.cfg index 5d52aea12..277cdc9fb 100644 --- a/tcl/target/stm8s.cfg +++ b/tcl/target/stm8s.cfg @@ -4,7 +4,7 @@ # stm8 devices support SWIM transports only. # -transport select stlink_swim +transport select swim if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME @@ -62,7 +62,7 @@ if { [info exists BLOCKSIZE] } { set _BLOCKSIZE 0x80 } -hla newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0 +swim newtap $_CHIPNAME cpu set _TARGETNAME $_CHIPNAME.cpu From 72f67790cf21b6328c9e599fb549b81f805694fc Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 4 Feb 2020 12:53:54 +0100 Subject: [PATCH 320/354] stlink: simplify mem R/W with SWIM Thanks to API separation between SWIM and the other transports, we can easily split the memory read/write for SWIM from the rest of the code. While there, use the macro STLINK_DATA_SIZE as size of data chunks that can be read/write in SWIM. This was not implemented before. Change-Id: I7d913c92539007e4d914480bacc0126a8f0e9705 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5531 Tested-by: jenkins --- src/jtag/drivers/stlink_usb.c | 48 ++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 4c5081c9e..c866dc54d 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -2322,11 +2322,6 @@ static int stlink_usb_read_mem(void *handle, uint32_t addr, uint32_t size, if (count < bytes_remaining) bytes_remaining = count; - if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { - retval = stlink_swim_readbytes(handle, addr, bytes_remaining, buffer); - if (retval != ERROR_OK) - return retval; - } else /* * all stlink support 8/32bit memory read/writes and only from * stlink V2J26 there is support for 16 bit memory read/write. @@ -2407,11 +2402,6 @@ static int stlink_usb_write_mem(void *handle, uint32_t addr, uint32_t size, if (count < bytes_remaining) bytes_remaining = count; - if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { - retval = stlink_swim_writebytes(handle, addr, bytes_remaining, buffer); - if (retval != ERROR_OK) - return retval; - } else /* * all stlink support 8/32bit memory read/writes and only from * stlink V2J26 there is support for 16 bit memory read/write. @@ -3552,13 +3542,47 @@ static int stlink_swim_op_srst(void) static int stlink_swim_op_read_mem(uint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer) { - return stlink_usb_read_mem(stlink_dap_handle, addr, size, count, buffer); + int retval; + uint32_t bytes_remaining; + + LOG_DEBUG_IO("read at 0x%08x len %d*0x%08x", addr, size, count); + count *= size; + + while (count) { + bytes_remaining = (count > STLINK_DATA_SIZE) ? STLINK_DATA_SIZE : count; + retval = stlink_swim_readbytes(stlink_dap_handle, addr, bytes_remaining, buffer); + if (retval != ERROR_OK) + return retval; + + buffer += bytes_remaining; + addr += bytes_remaining; + count -= bytes_remaining; + } + + return ERROR_OK; } static int stlink_swim_op_write_mem(uint32_t addr, uint32_t size, uint32_t count, const uint8_t *buffer) { - return stlink_usb_write_mem(stlink_dap_handle, addr, size, count, buffer); + int retval; + uint32_t bytes_remaining; + + LOG_DEBUG_IO("write at 0x%08x len %d*0x%08x", addr, size, count); + count *= size; + + while (count) { + bytes_remaining = (count > STLINK_DATA_SIZE) ? STLINK_DATA_SIZE : count; + retval = stlink_swim_writebytes(stlink_dap_handle, addr, bytes_remaining, buffer); + if (retval != ERROR_OK) + return retval; + + buffer += bytes_remaining; + addr += bytes_remaining; + count -= bytes_remaining; + } + + return ERROR_OK; } static int stlink_swim_op_reconnect(void) From ce9e21b769358b6408aada59810c33544bd8df4d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 28 Jan 2020 15:53:06 +0100 Subject: [PATCH 321/354] stlink: simplify handling of SWIM Now that SWIM is not accessed through HLA anymore, decouple the SWIM code and remove the conditional execution. Fix the inconsistency of the return type for stlink_usb_state() in case of SWIM (returns ERROR_OK while type is enum target_state) introduced by commit 3de6b5f6e52f ("jtag/drivers/stlink_usb : implemented and repaired SWIM support"). The code added by commit above in stlink_usb_state() is an hack to reuse existing HLA API to perform a reconnect. Move the SWIM specific code from stlink_usb_state() to a dedicated stlink_swim_op_reconnect() that provides consistent data type. Change-Id: I3fe175fef00b0735bea6139b057f217a080c9d38 Signed-off-by: Antonio Borneo Fixes: 3de6b5f6e52f ("jtag/drivers/stlink_usb : implemented and repaired SWIM support") Reviewed-on: http://openocd.zylin.com/5532 Tested-by: jenkins --- src/jtag/drivers/stlink_usb.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index c866dc54d..7281e5843 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -1761,18 +1761,6 @@ static enum target_state stlink_usb_state(void *handle) assert(handle != NULL); - if (h->st_mode == STLINK_MODE_DEBUG_SWIM) { - res = stlink_usb_mode_enter(handle, h->st_mode); - if (res != ERROR_OK) - return TARGET_UNKNOWN; - - res = stlink_swim_resync(handle); - if (res != ERROR_OK) - return TARGET_UNKNOWN; - - return ERROR_OK; - } - if (h->reconnect_pending) { LOG_INFO("Previous state query failed, trying to reconnect"); res = stlink_usb_mode_enter(handle, h->st_mode); @@ -1892,9 +1880,6 @@ static int stlink_usb_reset(void *handle) assert(handle != NULL); - if (h->st_mode == STLINK_MODE_DEBUG_SWIM) - return stlink_swim_generate_rst(handle); - stlink_usb_init_buffer(handle, h->rx_ep, 2); h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; @@ -3536,7 +3521,7 @@ static void stlink_dap_op_quit(struct adiv5_dap *dap) static int stlink_swim_op_srst(void) { - return stlink_usb_reset(stlink_dap_handle); + return stlink_swim_generate_rst(stlink_dap_handle); } static int stlink_swim_op_read_mem(uint32_t addr, uint32_t size, @@ -3587,7 +3572,13 @@ static int stlink_swim_op_write_mem(uint32_t addr, uint32_t size, static int stlink_swim_op_reconnect(void) { - return stlink_usb_state(stlink_dap_handle); + int retval; + + retval = stlink_usb_mode_enter(stlink_dap_handle, STLINK_MODE_DEBUG_SWIM); + if (retval != ERROR_OK) + return retval; + + return stlink_swim_resync(stlink_dap_handle); } static int stlink_dap_config_trace(bool enabled, From cc5889883f0b4660d5173f89543da02014f54b9c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 19 Mar 2020 12:12:20 +0100 Subject: [PATCH 322/354] Revert "adapter: expose HLA interface in struct adapter_driver" No reason to keep longer this temporary hack. Remove it by reverting the original commit. Change-Id: I5c6dcdb1f4755b7dba4c03a5033913ef8db35e18 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5533 Tested-by: jenkins --- src/jtag/hla/hla_interface.c | 3 --- src/jtag/interface.h | 6 ------ 2 files changed, 9 deletions(-) diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c index 064c268e4..6d5cdc5e7 100644 --- a/src/jtag/hla/hla_interface.c +++ b/src/jtag/hla/hla_interface.c @@ -361,7 +361,4 @@ struct adapter_driver hl_adapter_driver = { .poll_trace = &hl_interface_poll_trace, /* no ops for HLA, targets hla_target and stm8 intercept them all */ - - /* FIXME: helper to simplify transition of HLA drivers. To be removed */ - .hla_if = &hl_if, }; diff --git a/src/jtag/interface.h b/src/jtag/interface.h index a471aa96d..42598c1ae 100644 --- a/src/jtag/interface.h +++ b/src/jtag/interface.h @@ -38,9 +38,6 @@ */ -/* FIXME: prototype to simplify transition of HLA drivers. To be removed */ -struct hl_interface_s; - /** implementation of wrapper function tap_set_state() */ void tap_set_state_impl(tap_state_t new_state); @@ -366,9 +363,6 @@ struct adapter_driver { /* SWIM APIs */ const struct swim_driver *swim_ops; - - /* FIXME: helper to simplify transition of HLA drivers. To be removed */ - struct hl_interface_s *hla_if; }; extern const char * const jtag_only[]; From 1156fcd79e2700c7094b0a5ab435a4b7f31a8f41 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 26 Mar 2020 10:49:04 +0100 Subject: [PATCH 323/354] tcl/board: add board ST nucleo-8l152r8 The transport SWIM is selected twice, in board and in target, thus a warning is generated at run-time. It should be fixed by remove a line in the target file, but does not harm so let's keep it there for the time being. Change-Id: I479004dc16005a330d552c8dbd5def61690f9b9f Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5543 Tested-by: jenkins --- tcl/board/st_nucleo_8l152r8.cfg | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tcl/board/st_nucleo_8l152r8.cfg diff --git a/tcl/board/st_nucleo_8l152r8.cfg b/tcl/board/st_nucleo_8l152r8.cfg new file mode 100644 index 000000000..d3372693d --- /dev/null +++ b/tcl/board/st_nucleo_8l152r8.cfg @@ -0,0 +1,10 @@ +# This is a ST NUCLEO 8L152R8 board with a single STM8L152R8T6 chip. +# http://www.st.com/en/evaluation-tools/nucleo-8l152r8.html + +source [find interface/stlink-dap.cfg] + +transport select swim + +source [find target/stm8l152.cfg] + +reset_config srst_only From 2bc24c06d3ae11d3ec5b128cb1af556669e6c708 Mon Sep 17 00:00:00 2001 From: Ake Rehnman Date: Sun, 29 Mar 2020 21:57:53 +0200 Subject: [PATCH 324/354] stm8 target: make adapter speed settings work Previously the adapter speed settings were hard-coded to connect with low speed then switch over to high speed regardless what was mentioned in the cfg files. Now the stm8 target intercept adapter speed settings and configure the stm8 control registers accordingly. Change-Id: I7419514e5214e4b43b9d51253cf5b7f04a233533 Signed-off-by: Ake Rehnman Reviewed-on: http://openocd.zylin.com/5548 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/stm8.c | 40 +++++++++++++++++++++++++++++----------- tcl/target/stm8l.cfg | 6 ++++-- tcl/target/stm8s.cfg | 6 ++++-- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/target/stm8.c b/src/target/stm8.c index c06e0fae7..ce8cfaa51 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -45,6 +45,8 @@ static int stm8_set_breakpoint(struct target *target, static void stm8_enable_watchpoints(struct target *target); static int stm8_unset_watchpoint(struct target *target, struct watchpoint *watchpoint); +static int (*adapter_speed)(int speed); +extern struct adapter_driver *adapter_driver; static const struct { unsigned id; @@ -797,8 +799,35 @@ static int stm8_read_memory(struct target *target, target_addr_t address, return retval; } +static int stm8_speed(int speed) +{ + int retval; + uint8_t csr; + + LOG_DEBUG("stm8_speed: %d", speed); + + csr = SAFE_MASK | SWIM_DM; + if (speed >= SWIM_FREQ_HIGH) + csr |= HS; + + LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS:%d)", csr & HS ? 1 : 0); + retval = stm8_write_u8(NULL, SWIM_CSR, csr); + if (retval != ERROR_OK) + return retval; + return adapter_speed(speed); +} + static int stm8_init(struct command_context *cmd_ctx, struct target *target) { + /* + * FIXME: this is a temporarily hack that needs better implementation. + * Being the only overwrite of adapter_driver, it prevents declaring const + * the struct adapter_driver. + * intercept adapter_driver->speed() calls + */ + adapter_speed = adapter_driver->speed; + adapter_driver->speed = stm8_speed; + stm8_build_reg_cache(target); return ERROR_OK; @@ -1660,17 +1689,6 @@ static int stm8_examine(struct target *target) if (!target_was_examined(target)) { if (!stm8->swim_configured) { - /* set SWIM_CSR = 0xa0 (enable mem access & mask reset) */ - LOG_DEBUG("writing A0 to SWIM_CSR (SAFE_MASK + SWIM_DM)"); - retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM); - if (retval != ERROR_OK) - return retval; - /* set high speed */ - LOG_DEBUG("writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS)"); - retval = stm8_write_u8(target, SWIM_CSR, SAFE_MASK + SWIM_DM + HS); - if (retval != ERROR_OK) - return retval; - jtag_config_khz(SWIM_FREQ_HIGH); stm8->swim_configured = true; /* Now is the time to deassert reset if connect_under_reset. diff --git a/tcl/target/stm8l.cfg b/tcl/target/stm8l.cfg index 782350f78..a06c4cb60 100644 --- a/tcl/target/stm8l.cfg +++ b/tcl/target/stm8l.cfg @@ -78,8 +78,10 @@ $_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocks # Set stm8l type $_TARGETNAME configure -enable_stm8l -# Set low speed at debug entry -adapter speed 363 +# Set high speed +adapter speed 800 +# Set low speed +#adapter speed 363 reset_config srst_only diff --git a/tcl/target/stm8s.cfg b/tcl/target/stm8s.cfg index 277cdc9fb..2dae65515 100644 --- a/tcl/target/stm8s.cfg +++ b/tcl/target/stm8s.cfg @@ -75,8 +75,10 @@ $_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocks # Uncomment this line to enable interrupts while instruction step #$_TARGETNAME configure -enable_step_irq -# Set low speed at debug entry -adapter speed 363 +# Set high speed +adapter speed 800 +# Set low speed +#adapter speed 363 reset_config srst_only From af0db36f92827d24f16c321db4c9636ac37a5f91 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 23 Mar 2020 15:58:01 +0100 Subject: [PATCH 325/354] stlink: default dapdirect to SWD instead of JTAG When the transport is not specified, OpenOCD uses the first listed by the selected adapter driver. The old HLA driver for stlink lists SWD as first. The new driver dapdirect instead lists JTAG, making more difficult a fallback to HLA when dapdirect is not available due to old stlink FW. Plus, in case of JTAG wiring, SWD is still possible, while the opposite is not. Reorder the list of transports to grant the default to SWD. Change-Id: Id9c529e921b148d5b352d4603a9028c2a5f15d83 Signed-off-by: Antonio Borneo Suggested-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5538 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/drivers/stlink_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 7281e5843..79f2f7ee2 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -3782,7 +3782,7 @@ static const struct swim_driver stlink_swim_ops = { .reconnect = stlink_swim_op_reconnect, }; -static const char *const stlink_dap_transport[] = { "dapdirect_jtag", "dapdirect_swd", "swim", NULL }; +static const char *const stlink_dap_transport[] = { "dapdirect_swd", "dapdirect_jtag", "swim", NULL }; struct adapter_driver stlink_dap_adapter_driver = { .name = "st-link", From b342c67f7786fd17734763902dcb0c39286834a0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 15 May 2020 14:55:42 +0200 Subject: [PATCH 326/354] stlink: fix incorrectly returned error on v2j28 Firmware v2j28 introduces the API to open and close the AP, but closing AP always returns error 0x1d (STLINK_BAD_AP_ERROR). Ignore the error returned by the bogus firmware on closing AP. Change-Id: I992ddbf7acb10f1d376ed8f781eeb3344605b85d Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5683 Tested-by: jenkins --- src/jtag/drivers/stlink_usb.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 79f2f7ee2..116d71c6c 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -319,6 +319,7 @@ struct stlink_usb_handle_s { #define STLINK_F_HAS_AP_INIT BIT(7) #define STLINK_F_HAS_DPBANKSEL BIT(8) #define STLINK_F_HAS_RW8_512BYTES BIT(9) +#define STLINK_F_FIX_CLOSE_AP BIT(10) /* aliases */ #define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE @@ -1030,6 +1031,10 @@ static int stlink_usb_version(void *handle) if (h->version.jtag >= 28) flags |= STLINK_F_HAS_AP_INIT; + /* API required to return proper error code on close AP from J29 */ + if (h->version.jtag >= 29) + flags |= STLINK_F_FIX_CLOSE_AP; + /* Banked regs (DPv1 & DPv2) support from V2J32 */ if (h->version.jtag >= 32) flags |= STLINK_F_HAS_DPBANKSEL; @@ -1057,6 +1062,9 @@ static int stlink_usb_version(void *handle) /* API required to init AP before any AP access */ flags |= STLINK_F_HAS_AP_INIT; + /* API required to return proper error code on close AP */ + flags |= STLINK_F_FIX_CLOSE_AP; + /* Banked regs (DPv1 & DPv2) support from V3J2 */ if (h->version.jtag >= 2) flags |= STLINK_F_HAS_DPBANKSEL; @@ -3073,7 +3081,12 @@ static int stlink_usb_close_access_port(void *handle, unsigned char ap_num) h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_CLOSE_AP_DBG; h->cmdbuf[h->cmdidx++] = ap_num; - return stlink_usb_xfer_errcheck(handle, h->databuf, 2); + /* ignore incorrectly returned error on bogus FW */ + if (h->version.flags & STLINK_F_FIX_CLOSE_AP) + return stlink_usb_xfer_errcheck(handle, h->databuf, 2); + else + return stlink_usb_xfer_noerrcheck(handle, h->databuf, 2); + } /** */ From 7456e6bac5a3f13818d16660f3cd049a73a6e3fb Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 21 May 2020 13:24:32 +0200 Subject: [PATCH 327/354] stlink: fix open AP for v2j37 and v3j7 The new stlink firmware requires opening the AP before issuing any operation. In the current code we have a 'questionable' check about the core model to set the TAR autoincrement, that is issued without opening the AP, thus causing a STLINK_BAD_AP_ERROR. Modify the AP open API to handle this case and open AP#0 before the memory access to check the core model. Change-Id: I576955b5094bd41d63ff1fbad7b4fd9433253321 Signed-off-by: Antonio Borneo Reported-by: Andreas Bolsch Reviewed-on: http://openocd.zylin.com/5691 Tested-by: jenkins Reviewed-by: Andreas Bolsch --- src/jtag/drivers/stlink_usb.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 116d71c6c..3fdb126cf 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -361,6 +361,7 @@ static int stlink_swim_status(void *handle); void stlink_dump_speed_map(const struct speed_map *map, unsigned int map_size); static int stlink_get_com_freq(void *handle, bool is_jtag, struct speed_map *map); static int stlink_speed(void *handle, int khz, bool query); +static int stlink_usb_open_ap(void *handle, unsigned short apsel); /** */ static unsigned int stlink_usb_block(void *handle) @@ -2972,6 +2973,7 @@ static int stlink_usb_open(struct hl_interface_param_s *param, enum stlink_mode h->max_mem_packet = (1 << 10); uint8_t buffer[4]; + stlink_usb_open_ap(h, 0); err = stlink_usb_read_mem32(h, CPUID, 4, buffer); if (err == ERROR_OK) { uint32_t cpuid = le_to_h_u32(buffer); @@ -3204,13 +3206,13 @@ static int stlink_dap_get_and_clear_error(void) return retval; } -/** */ -static int stlink_dap_open_ap(unsigned short apsel) +static int stlink_usb_open_ap(void *handle, unsigned short apsel) { + struct stlink_usb_handle_s *h = handle; int retval; /* nothing to do on old versions */ - if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_AP_INIT)) + if (!(h->version.flags & STLINK_F_HAS_AP_INIT)) return ERROR_OK; if (apsel > DP_APSEL_MAX) @@ -3219,7 +3221,7 @@ static int stlink_dap_open_ap(unsigned short apsel) if (test_bit(apsel, opened_ap)) return ERROR_OK; - retval = stlink_usb_init_access_port(stlink_dap_handle, apsel); + retval = stlink_usb_init_access_port(h, apsel); if (retval != ERROR_OK) return retval; @@ -3228,6 +3230,11 @@ static int stlink_dap_open_ap(unsigned short apsel) return ERROR_OK; } +static int stlink_dap_open_ap(unsigned short apsel) +{ + return stlink_usb_open_ap(stlink_dap_handle, apsel); +} + /** */ static int stlink_dap_closeall_ap(void) { From 3008756604b8b7a3811948cf66ed7e587efac349 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 20 Oct 2019 19:40:28 +0200 Subject: [PATCH 328/354] helper/command: strip replicated command name in log After commit 0840414f0e57 ("helper/command: do not replace new commands with ocd_ prefix"), the command name is present in argv[0], so there is no need to pass it directly. The current code causes the command name to be logged twice, once explicitly and then from the content of argv[0]: openocd -c 'debug_level 3; echo hello; shutdown' Debug: 13 3 command.c:142 script_debug(): command - echo echo hello Debug: 16 4 command.c:142 script_debug(): command - shutdown shutdown Remove the command name from the arguments of the function script_debug(). Change-Id: I57860774f450ff717ee71ef9dc07590549a84319 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5660 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/helper/command.c | 10 ++++------ src/helper/command.h | 3 +-- src/jtag/tcl.c | 6 +++--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index 4422b4abe..14746a095 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -126,13 +126,12 @@ extern struct command_context *global_cmd_ctx; /* dump a single line to the log for the command. * Do nothing in case we are not at debug level 3 */ -void script_debug(Jim_Interp *interp, const char *name, - unsigned argc, Jim_Obj * const *argv) +void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const *argv) { if (debug_level < LOG_LVL_DEBUG) return; - char *dbg = alloc_printf("command - %s", name); + char *dbg = alloc_printf("command -"); for (unsigned i = 0; i < argc; i++) { int len; const char *w = Jim_GetString(argv[i], &len); @@ -213,7 +212,7 @@ static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv) struct command *c = interp->cmdPrivData; assert(c); - script_debug(interp, c->name, argc, argv); + script_debug(interp, argc, argv); return script_command_run(interp, argc, argv, c); } @@ -1032,8 +1031,7 @@ static int run_usage(Jim_Interp *interp, int argc_valid, int argc, Jim_Obj * con static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { - const char *cmd_name = Jim_GetString(argv[0], NULL); - script_debug(interp, cmd_name, argc, argv); + script_debug(interp, argc, argv); struct command_context *cmd_ctx = current_command_context(interp); struct command *c = cmd_ctx->commands; diff --git a/src/helper/command.h b/src/helper/command.h index 672ccd02b..a20c4620d 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -448,7 +448,6 @@ COMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label); #define COMMAND_PARSE_ENABLE(in, out) \ COMMAND_PARSE_BOOL(in, out, "enable", "disable") -void script_debug(Jim_Interp *interp, const char *cmd, - unsigned argc, Jim_Obj * const *argv); +void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const *argv); #endif /* OPENOCD_HELPER_COMMAND_H */ diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index f52cbd606..01210bd69 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -108,7 +108,7 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args endstate = TAP_IDLE; - script_debug(interp, "drscan", argc, args); + script_debug(interp, argc, args); /* validate arguments as numbers */ e = JIM_OK; @@ -229,7 +229,7 @@ static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *ar return JIM_ERR; } - script_debug(interp, "pathmove", argc, args); + script_debug(interp, argc, args); int i; for (i = 0; i < argc-1; i++) { @@ -261,7 +261,7 @@ static int Jim_Command_pathmove(Jim_Interp *interp, int argc, Jim_Obj *const *ar static int Jim_Command_flush_count(Jim_Interp *interp, int argc, Jim_Obj *const *args) { - script_debug(interp, "flush_count", argc, args); + script_debug(interp, argc, args); Jim_SetResult(interp, Jim_NewIntObj(interp, jtag_get_flush_queue_count())); From 80e8b019b0757ae895783dc7b8eaf424a6f6428c Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 13 May 2020 00:47:17 +0200 Subject: [PATCH 329/354] helper/command: fix check on value returned by jim API Either Jim_CreateCommand() and register_command_handler() return the jim error code JIM_OK/JIM_ERR. Fix the check and the initialization of retval. Change-Id: I3073c66764670128706ad979a43bb3edbbeb0ab0 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5661 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/helper/command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index 14746a095..193867fe8 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -380,14 +380,14 @@ struct command *register_command(struct command_context *context, if (NULL == c) return NULL; - int retval = ERROR_OK; + int retval = JIM_OK; if (NULL != cr->jim_handler && NULL == parent) { retval = Jim_CreateCommand(context->interp, cr->name, cr->jim_handler, NULL, NULL); } else if (NULL != cr->handler || NULL != parent) retval = register_command_handler(context, command_root(c)); - if (ERROR_OK != retval) { + if (retval != JIM_OK) { unregister_command(context, parent, name); c = NULL; } From 3b5a24c13b320fc0fd09e0dfacb5854b378eec34 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Tue, 12 May 2020 02:52:30 +0200 Subject: [PATCH 330/354] openocd: properly use jim data types The jim library exports all the data types through typedef, so there is no need to use the internal struct types. Fix the few remaining inconsistencies in the code. Change-Id: Id4ae0083563ea7a371833374e7b39f17158f66a4 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5662 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/rtos/rtos.c | 2 +- src/target/target.c | 2 +- src/target/target.h | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 221234828..ff0fb9286 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -121,7 +121,7 @@ int rtos_create(Jim_GetOptInfo *goi, struct target *target) { int x; const char *cp; - struct Jim_Obj *res; + Jim_Obj *res; int e; if (!goi->isconfigure && goi->argc != 0) { diff --git a/src/target/target.c b/src/target/target.c index b0deadb0b..c0953a3f1 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5011,7 +5011,7 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv if (goi.argc > 0 && strcmp(Jim_GetString(argv[1], NULL), "allow-defer") == 0) { /* consume it */ - struct Jim_Obj *obj; + Jim_Obj *obj; int e = Jim_GetOpt_Obj(&goi, &obj); if (e != JIM_OK) return e; diff --git a/src/target/target.h b/src/target/target.h index fc150442d..c69aa934a 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -32,6 +32,7 @@ #define OPENOCD_TARGET_TARGET_H #include +#include struct reg; struct trace; @@ -293,8 +294,8 @@ enum target_event { struct target_event_action { enum target_event event; - struct Jim_Interp *interp; - struct Jim_Obj *body; + Jim_Interp *interp; + Jim_Obj *body; struct target_event_action *next; }; From d8ac0086f957fabf63d596a3b8d396b110bc696d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 10 May 2020 10:57:59 +0200 Subject: [PATCH 331/354] helper/command: remove unused functions and make static local ones The function command_find_in_parent() is never used in OpenOCD, so remove it. The functions command_name() and [un]register_command() are only used internally in command.c, so make them static. Change-Id: Ide9842659796f4884fb6c1fcf5979b3b71b67abb Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5663 Reviewed-by: Andreas Fritiofson Tested-by: jenkins --- src/helper/command.c | 15 +++++++-------- src/helper/command.h | 42 +----------------------------------------- 2 files changed, 8 insertions(+), 49 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index 193867fe8..271e7b993 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -52,6 +52,10 @@ struct log_capture_state { Jim_Obj *output; }; +static int unregister_command(struct command_context *context, + struct command *parent, const char *name); +static char *command_name(struct command *c, char delim); + static void tcl_output(void *privData, const char *file, unsigned line, const char *function, const char *string) { @@ -242,11 +246,6 @@ struct command *command_find_in_context(struct command_context *cmd_ctx, { return command_find(cmd_ctx->commands, name); } -struct command *command_find_in_parent(struct command *parent, - const char *name) -{ - return command_find(parent->children, name); -} /** * Add the command into the linked list, sorted by name. @@ -358,7 +357,7 @@ static int register_command_handler(struct command_context *cmd_ctx, return retval; } -struct command *register_command(struct command_context *context, +static struct command *register_command(struct command_context *context, struct command *parent, const struct command_registration *cr) { if (!context || !cr->name) @@ -440,7 +439,7 @@ int unregister_all_commands(struct command_context *context, return ERROR_OK; } -int unregister_command(struct command_context *context, +static int unregister_command(struct command_context *context, struct command *parent, const char *name) { if ((!context) || (!name)) @@ -548,7 +547,7 @@ static char *__command_name(struct command *c, char delim, unsigned extra) return name; } -char *command_name(struct command *c, char delim) +static char *command_name(struct command *c, char delim) { return __command_name(c, delim, 0); } diff --git a/src/helper/command.h b/src/helper/command.h index a20c4620d..886bde86b 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -195,19 +195,9 @@ struct command { struct command *next; }; -/** - * @param c The command to be named. - * @param delim The character to place between command names. - * @returns A malloc'd string containing the full command name, - * which may include one or more ancestor components. Multiple names - * are separated by single spaces. The caller must free() the string - * when done with it. - */ -char *command_name(struct command *c, char delim); - /* * Commands should be registered by filling in one or more of these - * structures and passing them to register_command(). + * structures and passing them to [un]register_commands(). * * A conventioal format should be used for help strings, to provide both * usage and basic information: @@ -243,24 +233,6 @@ struct command_registration { /** Use this as the last entry in an array of command_registration records. */ #define COMMAND_REGISTRATION_DONE { .name = NULL, .chain = NULL } -/** - * Register a command @c handler that can be called from scripts during - * the execution @c mode specified. - * - * If @c parent is non-NULL, the new command will be registered as a - * sub-command under it; otherwise, it will be available as a top-level - * command. - * - * @param cmd_ctx The command_context in which to register the command. - * @param parent Register this command as a child of this, or NULL to - * register a top-level command. - * @param rec A command_registration record that contains the desired - * command parameters. - * @returns The new command, if successful; otherwise, NULL. - */ -struct command *register_command(struct command_context *cmd_ctx, - struct command *parent, const struct command_registration *rec); - /** * Register one or more commands in the specified context, as children * of @c parent (or top-level commends, if NULL). In a registration's @@ -279,16 +251,6 @@ struct command *register_command(struct command_context *cmd_ctx, int register_commands(struct command_context *cmd_ctx, struct command *parent, const struct command_registration *cmds); - -/** - * Unregisters command @c name from the given context, @c cmd_ctx. - * @param cmd_ctx The context of the registered command. - * @param parent The parent of the given command, or NULL. - * @param name The name of the command to unregister. - * @returns ERROR_OK on success, or an error code. - */ -int unregister_command(struct command_context *cmd_ctx, - struct command *parent, const char *name); /** * Unregisters all commands from the specfied context. * @param cmd_ctx The context that will be cleared of registered commands. @@ -300,8 +262,6 @@ int unregister_all_commands(struct command_context *cmd_ctx, struct command *command_find_in_context(struct command_context *cmd_ctx, const char *name); -struct command *command_find_in_parent(struct command *parent, - const char *name); /** * Update the private command data field for a command and all descendents. From 4c364b453488fb5d30c32dfb4f294c30d255d7bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Tue, 2 Jun 2020 11:52:01 +0100 Subject: [PATCH 332/354] Update Autotools Mythbuster link to avoid multiple redirects. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While I'm hoping to maintain the chain of redirects for the foreseeable future, it makes sense to point at the final URL now that Autotools Mythuster has had its domain for a long while. Change-Id: I6d912e3be0f81b25bec14746ebfee58f29f144b6 Signed-off-by: Diego Elio Pettenò Reviewed-on: http://openocd.zylin.com/5709 Reviewed-by: Antonio Borneo Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Andreas Fritiofson --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 00e83bbf4..2ff0329ed 100644 --- a/README +++ b/README @@ -277,7 +277,7 @@ e.g. for cross-building for Windows 32-bit with MinGW on Debian: To make pkg-config work nicely for cross-compiling, you might need an additional wrapper script as described at - http://www.flameeyes.eu/autotools-mythbuster/pkgconfig/cross-compiling.html + https://autotools.io/pkgconfig/cross-compiling.html This is needed to tell pkg-config where to look for the target libraries that OpenOCD depends on. Alternatively, you can specify From 3076fc601d9b4f8adf8aa080f550cb96290af60f Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Wed, 26 Feb 2020 12:51:35 +0100 Subject: [PATCH 333/354] tcl/boards: Rename 'dk-tm4c129.cfg' to 'ti_dk-tm4c129.cfg' The new filename has a proper vendor prefix. Keep the old configuration file for now but show a "deprecated" warning at runtime. Change-Id: I30fcb8f291d401acaa1fe665db0eeabc250d24b6 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5476 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Antonio Borneo --- tcl/board/dk-tm4c129.cfg | 15 ++------------- tcl/board/ti_dk-tm4c129.cfg | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 tcl/board/ti_dk-tm4c129.cfg diff --git a/tcl/board/dk-tm4c129.cfg b/tcl/board/dk-tm4c129.cfg index f1171af12..2c7de290d 100644 --- a/tcl/board/dk-tm4c129.cfg +++ b/tcl/board/dk-tm4c129.cfg @@ -1,14 +1,3 @@ -# -# TI Tiva C DK-TM4C129X Connected Development Kit -# -# http://www.ti.com/tool/dk-tm4c129x -# +echo "WARNING: board/dk-tm4c129.cfg is deprecated, please switch to board/ti_dk-tm4c129.cfg" -source [find interface/ti-icdi.cfg] - -transport select hla_jtag - -set WORKAREASIZE 0x8000 -set CHIPNAME tm4c129xnczad - -source [find target/stellaris.cfg] +source [find board/ti_dk-tm4c129.cfg] diff --git a/tcl/board/ti_dk-tm4c129.cfg b/tcl/board/ti_dk-tm4c129.cfg new file mode 100644 index 000000000..f1171af12 --- /dev/null +++ b/tcl/board/ti_dk-tm4c129.cfg @@ -0,0 +1,14 @@ +# +# TI Tiva C DK-TM4C129X Connected Development Kit +# +# http://www.ti.com/tool/dk-tm4c129x +# + +source [find interface/ti-icdi.cfg] + +transport select hla_jtag + +set WORKAREASIZE 0x8000 +set CHIPNAME tm4c129xnczad + +source [find target/stellaris.cfg] From fe13f61539b5ee27e14e8675c9ebe36a6ca034d4 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Wed, 26 Feb 2020 12:56:33 +0100 Subject: [PATCH 334/354] tcl/boards: Rename 'ek-tm4c123gxl.cfg' to 'ti_ek-tm4c123gxl.cfg' The new filename has a proper vendor prefix. Keep the old configuration file for now but show a "deprecated" warning at runtime. Change-Id: I13871ec13709055843e23b1b6da90694fd60505e Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5477 Tested-by: jenkins Reviewed-by: Karl Palsson Reviewed-by: Antonio Borneo --- tcl/board/ek-tm4c123gxl.cfg | 14 ++------------ tcl/board/ti_ek-tm4c123gxl.cfg | 13 +++++++++++++ 2 files changed, 15 insertions(+), 12 deletions(-) create mode 100644 tcl/board/ti_ek-tm4c123gxl.cfg diff --git a/tcl/board/ek-tm4c123gxl.cfg b/tcl/board/ek-tm4c123gxl.cfg index 4fc1050c7..3e497ba19 100644 --- a/tcl/board/ek-tm4c123gxl.cfg +++ b/tcl/board/ek-tm4c123gxl.cfg @@ -1,13 +1,3 @@ -# -# TI Tiva C Series ek-tm4c123gxl Launchpad Evaluation Kit -# -# http://www.ti.com/tool/ek-tm4c123gxl -# +echo "WARNING: board/ek-tm4c123gxl.cfg is deprecated, please switch to board/ti_ek-tm4c123gxl.cfg" -source [find interface/ti-icdi.cfg] - -transport select hla_jtag - -set WORKAREASIZE 0x8000 -set CHIPNAME tm4c123gh6pm -source [find target/stellaris.cfg] +source [find board/ti_ek-tm4c123gxl.cfg] diff --git a/tcl/board/ti_ek-tm4c123gxl.cfg b/tcl/board/ti_ek-tm4c123gxl.cfg new file mode 100644 index 000000000..4fc1050c7 --- /dev/null +++ b/tcl/board/ti_ek-tm4c123gxl.cfg @@ -0,0 +1,13 @@ +# +# TI Tiva C Series ek-tm4c123gxl Launchpad Evaluation Kit +# +# http://www.ti.com/tool/ek-tm4c123gxl +# + +source [find interface/ti-icdi.cfg] + +transport select hla_jtag + +set WORKAREASIZE 0x8000 +set CHIPNAME tm4c123gh6pm +source [find target/stellaris.cfg] From ae4113d877c8f2a0518fb3246610b1518ce7c03f Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Wed, 26 Feb 2020 12:58:27 +0100 Subject: [PATCH 335/354] tcl/boards: Rename 'ek-tm4c1294xl.cfg' to 'ti_ek-tm4c1294xl.cfg' The new filename has a proper vendor prefix. Keep the old configuration file for now but show a "deprecated" warning at runtime. Change-Id: If7465a752f47f3292e430c8b311148badfd384cd Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5478 Tested-by: jenkins Reviewed-by: Karl Palsson Reviewed-by: Antonio Borneo --- tcl/board/ek-tm4c1294xl.cfg | 15 ++------------- tcl/board/ti_ek-tm4c1294xl.cfg | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 tcl/board/ti_ek-tm4c1294xl.cfg diff --git a/tcl/board/ek-tm4c1294xl.cfg b/tcl/board/ek-tm4c1294xl.cfg index b3f384c0e..676386680 100644 --- a/tcl/board/ek-tm4c1294xl.cfg +++ b/tcl/board/ek-tm4c1294xl.cfg @@ -1,14 +1,3 @@ -# -# TI Tiva C Series ek-tm4c1294xl Launchpad Evaluation Kit -# -# http://www.ti.com/tool/ek-tm4c1294xl -# +echo "WARNING: board/ek-tm4c1294xl.cfg is deprecated, please switch to board/ti_ek-tm4c1294xl.cfg" -source [find interface/ti-icdi.cfg] - -transport select hla_jtag - -set WORKAREASIZE 0x8000 -set CHIPNAME tm4c1294ncpdt - -source [find target/stellaris.cfg] +source [find board/ti_ek-tm4c1294xl.cfg] diff --git a/tcl/board/ti_ek-tm4c1294xl.cfg b/tcl/board/ti_ek-tm4c1294xl.cfg new file mode 100644 index 000000000..b3f384c0e --- /dev/null +++ b/tcl/board/ti_ek-tm4c1294xl.cfg @@ -0,0 +1,14 @@ +# +# TI Tiva C Series ek-tm4c1294xl Launchpad Evaluation Kit +# +# http://www.ti.com/tool/ek-tm4c1294xl +# + +source [find interface/ti-icdi.cfg] + +transport select hla_jtag + +set WORKAREASIZE 0x8000 +set CHIPNAME tm4c1294ncpdt + +source [find target/stellaris.cfg] From 93e4bed0566fa783fc5f2524920f11ba250ea7dd Mon Sep 17 00:00:00 2001 From: tscn92 Date: Mon, 6 Apr 2020 16:05:08 +0200 Subject: [PATCH 336/354] jtag/drivers/bcm2835gpio: bcm2835gpio_init has been updated For jtag/drivers/bcm2835gpio dev_mem_fd has been updated within bcm2835gpio_init with the add on of gpio to mem. This permits the access to memory of GPIO without the need for root access. For failed attempt, a fallback to original memory follows. It should be noted that any printed error is relative to original memory ("dev/mem"). Tested on EFM32GG12B390F board Change-Id: I4540bdf62fb3b91a51221e277881adfae138dcc5 Signed-off-by: tscn92 Reviewed-on: http://openocd.zylin.com/5568 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/jtag/drivers/bcm2835gpio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/jtag/drivers/bcm2835gpio.c b/src/jtag/drivers/bcm2835gpio.c index bbc87d3dd..df557c5c6 100644 --- a/src/jtag/drivers/bcm2835gpio.c +++ b/src/jtag/drivers/bcm2835gpio.c @@ -466,7 +466,11 @@ static int bcm2835gpio_init(void) return ERROR_JTAG_INIT_FAILED; } - dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); + dev_mem_fd = open("/dev/gpiomem", O_RDWR | O_SYNC); + if (dev_mem_fd < 0) { + LOG_DEBUG("Cannot open /dev/gpiomem, fallback to /dev/mem"); + dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); + } if (dev_mem_fd < 0) { perror("open"); return ERROR_JTAG_INIT_FAILED; From cdb6918c87569e055e56db88b2726538c4617ad6 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Sun, 31 May 2020 11:12:05 +0100 Subject: [PATCH 337/354] arm_adi_v5: enhance command error reporting avoid the usage of ERROR_COMMAND_SYNTAX_ERROR when ERROR_COMMAND_ARGUMENT_INVALID is more adequate. Change-Id: Ic9aaedb93fedd45efee1b39f8ea20185f01af2da Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5654 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/target/arm_adi_v5.c | 49 +++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 2d47da3ea..5f6f1ff38 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -1610,8 +1610,10 @@ COMMAND_HANDLER(handle_dap_info_command) break; case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - if (apsel > DP_APSEL_MAX) - return ERROR_COMMAND_SYNTAX_ERROR; + if (apsel > DP_APSEL_MAX) { + command_print(CMD, "Invalid AP number"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } break; default: return ERROR_COMMAND_SYNTAX_ERROR; @@ -1633,8 +1635,10 @@ COMMAND_HANDLER(dap_baseaddr_command) case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) - return ERROR_COMMAND_SYNTAX_ERROR; + if (apsel > DP_APSEL_MAX) { + command_print(CMD, "Invalid AP number"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } break; default: return ERROR_COMMAND_SYNTAX_ERROR; @@ -1692,8 +1696,10 @@ COMMAND_HANDLER(dap_apsel_command) case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) - return ERROR_COMMAND_SYNTAX_ERROR; + if (apsel > DP_APSEL_MAX) { + command_print(CMD, "Invalid AP number"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } break; default: return ERROR_COMMAND_SYNTAX_ERROR; @@ -1722,7 +1728,7 @@ COMMAND_HANDLER(dap_apcsw_command) if (csw_val & (CSW_SIZE_MASK | CSW_ADDRINC_MASK)) { LOG_ERROR("CSW value cannot include 'Size' and 'AddrInc' bit-fields"); - return ERROR_COMMAND_SYNTAX_ERROR; + return ERROR_COMMAND_ARGUMENT_INVALID; } apcsw = csw_val; break; @@ -1731,7 +1737,7 @@ COMMAND_HANDLER(dap_apcsw_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], csw_mask); if (csw_mask & (CSW_SIZE_MASK | CSW_ADDRINC_MASK)) { LOG_ERROR("CSW mask cannot include 'Size' and 'AddrInc' bit-fields"); - return ERROR_COMMAND_SYNTAX_ERROR; + return ERROR_COMMAND_ARGUMENT_INVALID; } apcsw = (apcsw & ~csw_mask) | (csw_val & csw_mask); break; @@ -1758,8 +1764,10 @@ COMMAND_HANDLER(dap_apid_command) case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) - return ERROR_COMMAND_SYNTAX_ERROR; + if (apsel > DP_APSEL_MAX) { + command_print(CMD, "Invalid AP number"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } break; default: return ERROR_COMMAND_SYNTAX_ERROR; @@ -1789,13 +1797,18 @@ COMMAND_HANDLER(dap_apreg_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) - return ERROR_COMMAND_SYNTAX_ERROR; + if (apsel > DP_APSEL_MAX) { + command_print(CMD, "Invalid AP number"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + ap = dap_ap(dap, apsel); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg); - if (reg >= 256 || (reg & 3)) - return ERROR_COMMAND_SYNTAX_ERROR; + if (reg >= 256 || (reg & 3)) { + command_print(CMD, "Invalid reg value (should be less than 256 and 4 bytes aligned)"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } if (CMD_ARGC == 3) { COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); @@ -1839,8 +1852,10 @@ COMMAND_HANDLER(dap_dpreg_command) return ERROR_COMMAND_SYNTAX_ERROR; COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], reg); - if (reg >= 256 || (reg & 3)) - return ERROR_COMMAND_SYNTAX_ERROR; + if (reg >= 256 || (reg & 3)) { + command_print(CMD, "Invalid reg value (should be less than 256 and 4 bytes aligned)"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } if (CMD_ARGC == 2) { COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); @@ -1871,7 +1886,7 @@ COMMAND_HANDLER(dap_ti_be_32_quirks_command) case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], enable); if (enable > 1) - return ERROR_COMMAND_SYNTAX_ERROR; + return ERROR_COMMAND_ARGUMENT_INVALID; break; default: return ERROR_COMMAND_SYNTAX_ERROR; From 2d3bbcd56656b5f2a708541d42c6c85371323730 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Sun, 31 May 2020 11:46:56 +0100 Subject: [PATCH 338/354] arm_adi_v5: dap_ti_be_32_quirks_command minor simplification use handle_command_parse_bool within dap_ti_be_32_quirks_command to make it shorter and simpler. Change-Id: Ice179cc477933b27e27235dc2ade23fe655e233d Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5708 Tested-by: jenkins Reviewed-by: Marc Schink Reviewed-by: Antonio Borneo --- src/target/arm_adi_v5.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 5f6f1ff38..f19514c85 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -1878,24 +1878,8 @@ COMMAND_HANDLER(dap_dpreg_command) COMMAND_HANDLER(dap_ti_be_32_quirks_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t enable = dap->ti_be_32_quirks; - - switch (CMD_ARGC) { - case 0: - break; - case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], enable); - if (enable > 1) - return ERROR_COMMAND_ARGUMENT_INVALID; - break; - default: - return ERROR_COMMAND_SYNTAX_ERROR; - } - dap->ti_be_32_quirks = enable; - command_print(CMD, "TI BE-32 quirks mode %s", - enable ? "enabled" : "disabled"); - - return 0; + return CALL_COMMAND_HANDLER(handle_command_parse_bool, &dap->ti_be_32_quirks, + "TI BE-32 quirks mode"); } const struct command_registration dap_instance_commands[] = { From ffc1ca4b91757911c53d5dc86cae55eb00d858d5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 29 May 2020 10:42:43 +0200 Subject: [PATCH 339/354] nor/kinetis: add keep-alive during flash write Flashing Kinetis MCU MK22FX512VLH12 takes longer than one second, thus gdb connection can timeout. Before commit 7f260f5009a7 ("helper/command: Handle Tcl return values consistently") the openocd timeout warning was masked by a bug in gdb_put_packet() that resets the timeout counter if any message is logged out. The commit above removes one log message and the timeout warning is now triggered. While the bug in gdb_put_packet() is still to be fixed, the reason of the timeout is the lack of keep_alive() calls in kinetis flash driver. Add keep_alive() call at every iteration in function kinetis_write_sections(), that is reported as core write function in chunks of 1024 bytes in the log from the reporter. Add also a keep_alive() call at every iteration in function kinetis_write_inner(). This part is not present in the log but, by code analysis, it represents another critical loop. Change-Id: I38e631b36c7eb2f1e21cef68710ce47c03d3edda Signed-off-by: Antonio Borneo Reported-by: Jonatan Hatakeyama Zeidler Reviewed-on: http://openocd.zylin.com/5703 Tested-by: jenkins Reviewed-by: --- src/flash/nor/kinetis.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index bceaf8474..084e009ee 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -1793,6 +1793,8 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer buffer += size; offset += size; count -= size; + + keep_alive(); } free(buffer_aligned); @@ -1885,6 +1887,8 @@ static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer, buffer += 4; offset += 4; words_remaining--; + + keep_alive(); } } free(new_buffer); From 1fa66d3633862d824420fb90b5b63e41e415d70e Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 29 May 2020 12:00:35 +0200 Subject: [PATCH 340/354] log: fix kept_alive() and report expired timeout The kept_alive() function is called to inform the keep-alive code that a keep-alive as been just kicked through some other path. But kept_alive() erroneously resets the timeout counter without checking if it has already expired, thus masking a potential timeout. Check if timeout counter has expired during kept_alive(). While there, put the timeout values in macros and explicit the units in the timeout messages. Change-Id: Iaf6368b44e5b5352b1cc4e7efbb2368575dcfa08 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5705 Reviewed-by: Tested-by: jenkins --- src/helper/log.c | 54 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/src/helper/log.c b/src/helper/log.c index 380f548f4..31122554e 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -401,25 +401,43 @@ char *alloc_printf(const char *format, ...) * fast when invoked more often than every 500ms. * */ +#define KEEP_ALIVE_KICK_TIME_MS 500 +#define KEEP_ALIVE_TIMEOUT_MS 1000 + +static void gdb_timeout_warning(int64_t delta_time) +{ + extern int gdb_actual_connections; + + if (gdb_actual_connections) + LOG_WARNING("keep_alive() was not invoked in the " + "%d ms timelimit. GDB alive packet not " + "sent! (%" PRId64 " ms). Workaround: increase " + "\"set remotetimeout\" in GDB", + KEEP_ALIVE_TIMEOUT_MS, + delta_time); + else + LOG_DEBUG("keep_alive() was not invoked in the " + "%d ms timelimit (%" PRId64 " ms). This may cause " + "trouble with GDB connections.", + KEEP_ALIVE_TIMEOUT_MS, + delta_time); +} + void keep_alive(void) { current_time = timeval_ms(); - if (current_time-last_time > 1000) { - extern int gdb_actual_connections; - if (gdb_actual_connections) - LOG_WARNING("keep_alive() was not invoked in the " - "1000ms timelimit. GDB alive packet not " - "sent! (%" PRId64 "). Workaround: increase " - "\"set remotetimeout\" in GDB", - current_time-last_time); - else - LOG_DEBUG("keep_alive() was not invoked in the " - "1000ms timelimit (%" PRId64 "). This may cause " - "trouble with GDB connections.", - current_time-last_time); + int64_t delta_time = current_time - last_time; + + if (delta_time > KEEP_ALIVE_TIMEOUT_MS) { + last_time = current_time; + + gdb_timeout_warning(delta_time); } - if (current_time-last_time > 500) { + + if (delta_time > KEEP_ALIVE_KICK_TIME_MS) { + last_time = current_time; + /* this will keep the GDB connection alive */ LOG_USER_N("%s", ""); @@ -430,8 +448,6 @@ void keep_alive(void) * * These functions should be invoked at a well defined spot in server.c */ - - last_time = current_time; } } @@ -439,7 +455,13 @@ void keep_alive(void) void kept_alive(void) { current_time = timeval_ms(); + + int64_t delta_time = current_time - last_time; + last_time = current_time; + + if (delta_time > KEEP_ALIVE_TIMEOUT_MS) + gdb_timeout_warning(delta_time); } /* if we sleep for extended periods of time, we must invoke keep_alive() intermittantly */ From 37330f89d789e5b0a74aa14f7a7bfcfb4260abff Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Wed, 27 May 2020 00:03:45 +0200 Subject: [PATCH 341/354] target/cortex-m: enable C_DEBUGEN during examine Current code for Cortex M does not set C_DEBUGEN as soon as possible, (which means during target examine), but later-on either: 1) at command 'halt' (e.g. for 'gdb-attach' event); 2) at command 'soft_reset_halt'; 3) at commands 'reset', 'reset halt' or 'reset init'; 4) during polling, but only if the target: = enter in 'double fault', or = exit from a reset, or = halts (not possible if C_DEBUGEN is not set) Plus, if commands in 1) or 2) are executed before the very first poll of the target, the value of 'cortex_m->dcb_dhcsr' is used not initialized while writing it back in DCB_DHCSR. Another side effect of this situation is that it's possible to set a HW breakpoint with the target running, while C_DEBUGEN is not set. Accordingly to [1], C1.3.1 "Debug authentication": When DGBEN is LOW and DHCSR.S_HALT == 0: ... FPB breakpoints do not generate an entry to Debug state and, if no DebugMonitor exception is generated, will escalate to HardFault, Lockup, or be ignored. On STM32MP15x I get HW breakpoint ignored, while on STM32F411 I get HardFault. E.g. following these steps: - power-on a pre-flashed board that starts running the firmware; - connect openocd, without halting or resetting the board; - set a HW breakpoint to some address often executed; - wait, but the board doesn't halt ...; - type the command 'halt'; - if the Cortex-M has HardFault it would be visible and the fault is at the breakpoint address; - if no HardFault then type the command 'resume'; - wait and the board will finally halt at the HW breakpoint. A similar issue has been detected on Cortex-A code and fixed by commit bff87a7f28fb ("target/cortex_a: enable DSCR_HALT_DBG_MODE during examine"). Follow the same approach and set C_DEBUGEN during examine. Also, initialize 'cortex_m->dcb_dhcsr' during examine. [1] ARM DDI 0403E "ARM v7-M Architecture Reference Manual" Change-Id: I5b0b23403634f7dfce38f104bba9f59c33eb3e99 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5702 Tested-by: jenkins Reviewed-by: Andreas Fritiofson Reviewed-by: Tarek BOCHKATI Reviewed-by: Moritz Fischer --- src/target/cortex_m.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index e540f8507..d9bee0e53 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2230,6 +2230,19 @@ int cortex_m_examine(struct target *target) armv7m->debug_ap->tar_autoincr_block = (1 << 10); } + /* Enable debug requests */ + retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr); + if (retval != ERROR_OK) + return retval; + if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) { + uint32_t dhcsr = (cortex_m->dcb_dhcsr | C_DEBUGEN) & ~(C_HALT | C_STEP | C_MASKINTS); + + retval = target_write_u32(target, DCB_DHCSR, DBGKEY | (dhcsr & 0x0000FFFFUL)); + if (retval != ERROR_OK) + return retval; + cortex_m->dcb_dhcsr = dhcsr; + } + /* Configure trace modules */ retval = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr); if (retval != ERROR_OK) From f6b4079ce5793f86b2c26c6bfcc8c717e2c8a3c3 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 25 May 2020 21:37:12 +0200 Subject: [PATCH 342/354] libusb_helper: fix memory leak when no adapter is found When jtag_libusb_open() fails to find the adapter, it returns error but left libusb initialized causing memory leak of libusb internal data. Issue found with valgrind when no adapter or board is connected to the host, e.g. valgrind openocd -f board/st_nucleo_f4.cfg Close the libusb operations if jtag_libusb_open() has to return error. Change-Id: Ieb2f110be15705dafe80c099e7d83c07056c2a41 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5701 Tested-by: jenkins --- src/jtag/drivers/libusb_helper.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c index fbbfb4114..184882abc 100644 --- a/src/jtag/drivers/libusb_helper.c +++ b/src/jtag/drivers/libusb_helper.c @@ -208,6 +208,9 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], if (serial_mismatch) LOG_INFO("No device matches the serial string"); + if (retval != ERROR_OK) + libusb_exit(jtag_libusb_context); + return retval; } From 061cae171c9d2b6015a565dcc748dd04319e08cf Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 22 May 2020 18:08:55 +0200 Subject: [PATCH 343/354] target/mem_ap: fix two memory leaks The target mem_ap misses the method 'deinit_target' and does not free the memory allocated during 'target create' and 'configure'. Add the missing method and free the allocated memory. Issue identified with valgrind. Change-Id: If0d0114a75dd76a8b65c2d46d96c6085fd31a09d Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5700 Tested-by: jenkins --- src/target/mem_ap.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/target/mem_ap.c b/src/target/mem_ap.c index 29cd37a90..ade48b6d7 100644 --- a/src/target/mem_ap.c +++ b/src/target/mem_ap.c @@ -65,6 +65,15 @@ static int mem_ap_init_target(struct command_context *cmd_ctx, struct target *ta return ERROR_OK; } +static void mem_ap_deinit_target(struct target *target) +{ + LOG_DEBUG("%s", __func__); + + free(target->private_config); + free(target->arch_info); + return; +} + static int mem_ap_arch_state(struct target *target) { LOG_DEBUG("%s", __func__); @@ -169,6 +178,7 @@ struct target_type mem_ap_target = { .target_create = mem_ap_target_create, .init_target = mem_ap_init_target, + .deinit_target = mem_ap_deinit_target, .examine = mem_ap_examine, .target_jim_configure = adiv5_jim_configure, From 6f88aa0fb3bb7a91b5327b75e8fb772ed6d3be2d Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Fri, 22 May 2020 18:55:34 +0200 Subject: [PATCH 344/354] target/cortex_a: fix memory leak of register cache There is no method to free the register cache, allocated in armv4_5, so we get a memory leak. Issue identified by valgrind. Implement the method arm_free_reg_cache() and call it in cortex_a deinit and to exit for error during arm_dpm_setup(). Tested on dual cortex-A stm32mp15x. This change is inspired from similar fix in commit b01b5fe13a67 ("armv7m: Fix memory leak in register caching."). The same allocation is also used by target types "arm7tdmi", "arm9tdmi", "arm11" and "xscale" but they all lack the deinit method and I do not have relevant HW to test the fix. For such reasons they are not addressed in this patch. Change-Id: I4da1e1f12e36ec245d1f3b11a4eafcbd9a1d2e25 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5693 Tested-by: jenkins --- src/target/arm.h | 2 ++ src/target/arm_dpm.c | 1 + src/target/armv4_5.c | 21 +++++++++++++++++++++ src/target/cortex_a.c | 1 + 4 files changed, 25 insertions(+) diff --git a/src/target/arm.h b/src/target/arm.h index b39957495..3450260f0 100644 --- a/src/target/arm.h +++ b/src/target/arm.h @@ -272,6 +272,8 @@ struct arm_reg { }; struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm); +void arm_free_reg_cache(struct arm *arm); + struct reg_cache *armv8_build_reg_cache(struct target *target); extern const struct command_registration arm_command_handlers[]; diff --git a/src/target/arm_dpm.c b/src/target/arm_dpm.c index 495d63ec2..72215f90b 100644 --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -1100,6 +1100,7 @@ int arm_dpm_setup(struct arm_dpm *dpm) dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp)); if (!dpm->dbp || !dpm->dwp) { + arm_free_reg_cache(arm); free(dpm->dbp); free(dpm->dwp); return ERROR_FAIL; diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index b4581d5f1..58bc3390a 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -769,6 +769,27 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm) return cache; } +void arm_free_reg_cache(struct arm *arm) +{ + if (!arm || !arm->core_cache) + return; + + struct reg_cache *cache = arm->core_cache; + + for (unsigned int i = 0; i < cache->num_regs; i++) { + struct reg *reg = &cache->reg_list[i]; + + free(reg->feature); + free(reg->reg_data_type); + } + + free(cache->reg_list[0].arch_info); + free(cache->reg_list); + free(cache); + + arm->core_cache = NULL; +} + int arm_arch_state(struct target *target) { struct arm *arm = target_to_arm(target); diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index f71b15524..f562a7614 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -2959,6 +2959,7 @@ static void cortex_a_deinit_target(struct target *target) } free(cortex_a->brp_list); + arm_free_reg_cache(dpm->arm); free(dpm->dbp); free(dpm->dwp); free(target->private_config); From bd425de3fbb9ba73d4e24573e2b2262ba1b8a3f5 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Thu, 21 May 2020 16:03:17 +0200 Subject: [PATCH 345/354] jtag/tcl: fix memory leak in command 'irscan' If the function parse_u64() fails, we jump to return, thus leaking the memory just allocated in 'v'. Issue identified by clang. Move earlier the call to parse_u64() and the associated test, before memory allocation. While there, fix a possible NULL pointer dereferencing in case the calloc() fails, by testing for allocation failure. Change-Id: I6a77ee17aceb282bbdfefe7cdafeba2e0e7012f1 Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5692 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI --- src/jtag/tcl.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c index 01210bd69..d2f1f0db5 100644 --- a/src/jtag/tcl.c +++ b/src/jtag/tcl.c @@ -1129,14 +1129,19 @@ COMMAND_HANDLER(handle_irscan_command) return ERROR_FAIL; } - int field_size = tap->ir_length; - fields[i].num_bits = field_size; - uint8_t *v = calloc(1, DIV_ROUND_UP(field_size, 8)); - uint64_t value; retval = parse_u64(CMD_ARGV[i * 2 + 1], &value); if (ERROR_OK != retval) goto error_return; + + int field_size = tap->ir_length; + fields[i].num_bits = field_size; + uint8_t *v = calloc(1, DIV_ROUND_UP(field_size, 8)); + if (!v) { + LOG_ERROR("Out of memory"); + goto error_return; + } + buf_set_u64(v, 0, field_size, value); fields[i].out_value = v; fields[i].in_value = NULL; From f0909fe9e5f819d83c90c2622e27d98fa1b59046 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Mon, 6 May 2019 19:31:00 +0200 Subject: [PATCH 346/354] coding style: fix multi-line dereferencing Issue identified by checkpatch script from Linux kernel v5.1 using the command find src/ -type f -exec ./tools/scripts/checkpatch.pl \ -q --types MULTILINE_DEREFERENCE -f {} \; Change-Id: Icba05613e22a72ecc3e6a0aad7cb6b479496146f Signed-off-by: Antonio Borneo Reviewed-on: http://openocd.zylin.com/5629 Tested-by: jenkins Reviewed-by: Marc Schink --- src/rtos/linux.c | 21 +++++++-------------- src/target/etm.c | 4 ++-- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/rtos/linux.c b/src/rtos/linux.c index e85a3bdf8..63659bb05 100644 --- a/src/rtos/linux.c +++ b/src/rtos/linux.c @@ -995,10 +995,8 @@ static int linux_task_update(struct target *target, int context) if (context) thread_list->context = cpu_context_read(target, - thread_list-> - base_addr, - &thread_list-> - thread_info_addr); + thread_list->base_addr, + &thread_list->thread_info_addr); } else { /* it is a current thread no need to read context */ } @@ -1190,9 +1188,8 @@ int linux_gdb_T_packet(struct connection *connection, } else { /* delete item in the list */ linux_os->thread_list = - liste_del_task(linux_os-> - thread_list, &temp, - prev); + liste_del_task(linux_os->thread_list, + &temp, prev); linux_os->thread_count--; gdb_put_packet(connection, "E01", 3); return ERROR_OK; @@ -1323,9 +1320,7 @@ static int linux_thread_packet(struct connection *connection, char const *packet if (strncmp(packet, "qSymbol", 7) == 0) { if (rtos_qsymbol(connection, packet, packet_size) == 1) { linux_compute_virt2phys(target, - target->rtos-> - symbols[INIT_TASK]. - address); + target->rtos->symbols[INIT_TASK].address); } break; @@ -1376,8 +1371,7 @@ static int linux_thread_packet(struct connection *connection, char const *packet } if ((ct != NULL) && (ct->threadid != - target->rtos-> - current_threadid) + target->rtos->current_threadid) && (target->rtos->current_threadid != -1)) LOG_WARNING("WARNING! current GDB thread do not match " "current thread running. " @@ -1410,8 +1404,7 @@ static int linux_os_smp_init(struct target *target) while (head != (struct target_list *)NULL) { if (head->target->rtos != rtos) { struct linux_os *smp_os_linux = - (struct linux_os *)head->target->rtos-> - rtos_specific_params; + (struct linux_os *)head->target->rtos->rtos_specific_params; /* remap smp target on rtos */ free(head->target->rtos); head->target->rtos = rtos; diff --git a/src/target/etm.c b/src/target/etm.c index 5218a9e48..5d079ffa8 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -1074,8 +1074,8 @@ static int etmv1_analyze_trace(struct etm_context *ctx, struct command_invocatio (instruction.type == ARM_STM)) { int i; for (i = 0; i < 16; i++) { - if (instruction.info.load_store_multiple. - register_list & (1 << i)) { + if (instruction.info.load_store_multiple.register_list + & (1 << i)) { uint32_t data; if (etmv1_data(ctx, 4, &data) != 0) return ERROR_ETM_ANALYSIS_FAILED; From 4a5de86f5871a07c05d4d13f18a75ab4554d07cb Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Wed, 13 May 2020 15:03:44 -0700 Subject: [PATCH 347/354] flash: Add the Freedom E310-G002 SPI Flash Change-Id: Id9f4a209a6eacf186931b142e70a5b0458517be0 Signed-off-by: Alistair Francis Reviewed-on: http://openocd.zylin.com/5679 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tim Newsome --- src/flash/nor/fespi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/flash/nor/fespi.c b/src/flash/nor/fespi.c index 90242b1ad..05489fdfb 100644 --- a/src/flash/nor/fespi.c +++ b/src/flash/nor/fespi.c @@ -136,7 +136,8 @@ struct fespi_target { /* TODO !!! What is the right naming convention here? */ static const struct fespi_target target_devices[] = { /* name, tap_idcode, ctrl_base */ - { "Freedom E300 SPI Flash", 0x10e31913 , 0x10014000 }, + { "Freedom E310-G000 SPI Flash", 0x10e31913 , 0x10014000 }, + { "Freedom E310-G002 SPI Flash", 0x20000913 , 0x10014000 }, { NULL, 0, 0 } }; From 7e78c04f1c275176bdee8f9d2553300218164577 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Wed, 13 May 2020 15:04:16 -0700 Subject: [PATCH 348/354] board: Add the HiFive1 revB board configuration Change-Id: If186afcfd2c87414b9323569a16aed9a6054c883 Signed-off-by: Alistair Francis Reviewed-on: http://openocd.zylin.com/5680 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Tim Newsome --- tcl/board/sifive-hifive1-revb.cfg | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tcl/board/sifive-hifive1-revb.cfg diff --git a/tcl/board/sifive-hifive1-revb.cfg b/tcl/board/sifive-hifive1-revb.cfg new file mode 100644 index 000000000..292f1027a --- /dev/null +++ b/tcl/board/sifive-hifive1-revb.cfg @@ -0,0 +1,21 @@ +adapter speed 4000 + +adapter driver jlink +transport select jtag + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000913 + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 0x4000 -work-area-backup 0 + +flash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME.0 + +init + +jlink jtag 3 + +halt +flash protect 0 1 last off +echo "Ready for Remote Connections" From 9a690c6bdb18d722a99d5752ac9c3ae1733cf22e Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Thu, 23 Apr 2020 11:00:31 +0100 Subject: [PATCH 349/354] openocd: fix issue in WIN32 with TCP adapters Issue: server_quit is called before adapter_quit: In WIN32 only in server_quit we do an WSACleanup, which terminates/closes all active sockets. So if the adapter is TCP based, the adapter.quit handler will fail if it will need to send some commands through TCP. Example: close_socket in jtag_vpi_quit will fail in WIN32 because the socket is already closed and the errno is set as "Bad File Descriptor" To fix that we introduced new functions called server_host_os_entry/quit to manage specific OS setup (hence WSA for sockets in WINDOWS) in order to delay WSACleanup after adapter_quit(). Change-Id: Ie4afacafe123857f6ae300e376bdfcf0d8c027ac Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5456 Tested-by: jenkins Reviewed-by: Antonio Borneo --- src/openocd.c | 4 ++++ src/server/server.c | 17 +++++++++++++++-- src/server/server.h | 3 +++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/openocd.c b/src/openocd.c index 2a9a0b3d4..886228425 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -345,6 +345,8 @@ int openocd_main(int argc, char *argv[]) command_context_mode(cmd_ctx, COMMAND_CONFIG); command_set_output_handler(cmd_ctx, configuration_output_handler, NULL); + server_host_os_entry(); + /* Start the executable meat that can evolve into thread in future. */ ret = openocd_thread(argc, argv, cmd_ctx); @@ -360,6 +362,8 @@ int openocd_main(int argc, char *argv[]) adapter_quit(); + server_host_os_close(); + /* Shutdown commandline interface */ command_exit(cmd_ctx); diff --git a/src/server/server.c b/src/server/server.c index 07b7ae487..23a15ef9a 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -631,7 +631,7 @@ static void sigkey_handler(int sig) #endif -int server_preinit(void) +int server_host_os_entry(void) { /* this currently only calls WSAStartup on native win32 systems * before any socket operations are performed. @@ -647,7 +647,21 @@ int server_preinit(void) LOG_ERROR("Failed to Open Winsock"); return ERROR_FAIL; } +#endif + return ERROR_OK; +} +int server_host_os_close(void) +{ +#ifdef _WIN32 + WSACleanup(); +#endif + return ERROR_OK; +} + +int server_preinit(void) +{ +#ifdef _WIN32 /* register ctrl-c handler */ SetConsoleCtrlHandler(ControlHandler, TRUE); @@ -688,7 +702,6 @@ int server_quit(void) target_quit(); #ifdef _WIN32 - WSACleanup(); SetConsoleCtrlHandler(ControlHandler, FALSE); return ERROR_OK; diff --git a/src/server/server.h b/src/server/server.h index ab9b72f90..f4cc39d3a 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -80,6 +80,9 @@ int add_service(char *name, const char *port, void *priv); int remove_service(const char *name, const char *port); +int server_host_os_entry(void); +int server_host_os_close(void); + int server_preinit(void); int server_init(struct command_context *cmd_ctx); int server_quit(void); From bd6072072eabf3b0ad61ee63c78ccf53f49ab957 Mon Sep 17 00:00:00 2001 From: Tarek BOCHKATI Date: Mon, 27 Apr 2020 13:09:27 +0100 Subject: [PATCH 350/354] stlink: code factorization by introducing stlink_usb_exit_mode Change-Id: I4abd6432c4ef969e382bfed96cd19a49d9610000 Signed-off-by: Antonio Borneo Signed-off-by: Tarek BOCHKATI Reviewed-on: http://openocd.zylin.com/5612 Tested-by: jenkins --- src/jtag/drivers/stlink_usb.c | 67 +++++++++++++---------------------- 1 file changed, 24 insertions(+), 43 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 3fdb126cf..72975d5ac 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -1303,12 +1303,11 @@ static enum stlink_mode stlink_get_mode(enum hl_transports t) } /** */ -static int stlink_usb_init_mode(void *handle, bool connect_under_reset, int initial_interface_speed) +static int stlink_usb_exit_mode(void *handle) { int res; uint8_t mode; enum stlink_mode emode; - struct stlink_usb_handle_s *h = handle; assert(handle != NULL); @@ -1337,12 +1336,25 @@ static int stlink_usb_init_mode(void *handle, bool connect_under_reset, int init break; } - if (emode != STLINK_MODE_UNKNOWN) { - res = stlink_usb_mode_leave(handle, emode); + if (emode != STLINK_MODE_UNKNOWN) + return stlink_usb_mode_leave(handle, emode); - if (res != ERROR_OK) - return res; - } + return ERROR_OK; +} + +/** */ +static int stlink_usb_init_mode(void *handle, bool connect_under_reset, int initial_interface_speed) +{ + int res; + uint8_t mode; + enum stlink_mode emode; + struct stlink_usb_handle_s *h = handle; + + assert(handle != NULL); + + res = stlink_usb_exit_mode(handle); + if (res != ERROR_OK) + return res; res = stlink_usb_current_mode(handle, &mode); @@ -2683,45 +2695,14 @@ static int stlink_speed(void *handle, int khz, bool query) /** */ static int stlink_usb_close(void *handle) { - int res; - uint8_t mode; - enum stlink_mode emode; struct stlink_usb_handle_s *h = handle; - if (h && h->fd) - res = stlink_usb_current_mode(handle, &mode); - else - res = ERROR_FAIL; - /* do not exit if return code != ERROR_OK, - it prevents us from closing jtag_libusb */ - - if (res == ERROR_OK) { - /* try to exit current mode */ - switch (mode) { - case STLINK_DEV_DFU_MODE: - emode = STLINK_MODE_DFU; - break; - case STLINK_DEV_DEBUG_MODE: - emode = STLINK_MODE_DEBUG_SWD; - break; - case STLINK_DEV_SWIM_MODE: - emode = STLINK_MODE_DEBUG_SWIM; - break; - case STLINK_DEV_BOOTLOADER_MODE: - case STLINK_DEV_MASS_MODE: - default: - emode = STLINK_MODE_UNKNOWN; - break; - } - - if (emode != STLINK_MODE_UNKNOWN) - stlink_usb_mode_leave(handle, emode); - /* do not check return code, it prevent - us from closing jtag_libusb */ - } - - if (h && h->fd) + if (h && h->fd) { + stlink_usb_exit_mode(h); + /* do not check return code, it prevent + us from closing jtag_libusb */ jtag_libusb_close(h->fd); + } free(h); From b7d41ef96aaf371e71cb58f5fa7104f4a201ea27 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Fri, 15 May 2020 10:06:07 +0200 Subject: [PATCH 351/354] flash/nor/stm32l4x: Fix check for number of arguments The current version erroneously allows any number of arguments >= 1. Change-Id: I64156c11b48d411c72bebbf866954818cd036ff2 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5716 Tested-by: jenkins Reviewed-by: Tarek BOCHKATI Reviewed-by: Antonio Borneo --- src/flash/nor/stm32l4x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 38f8b3b99..94fcd3226 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -1238,7 +1238,7 @@ COMMAND_HANDLER(stm32l4_handle_option_write_command) COMMAND_HANDLER(stm32l4_handle_option_load_command) { - if (CMD_ARGC < 1) + if (CMD_ARGC != 1) return ERROR_COMMAND_SYNTAX_ERROR; struct flash_bank *bank; From 11116ef6ad875055a43cf9af1f228991349f2ba1 Mon Sep 17 00:00:00 2001 From: Edward Fewell Date: Wed, 3 Jun 2020 14:55:07 -0500 Subject: [PATCH 352/354] target/icepick.cfg: Add support for Test TAPs in ICEPick C In addition to the debug TAPs, the ICEPick C also supports a bank of Test TAPs (limited functionality intended for non-debuggable targets). Added support for Test TAPs to the icepick_c_tapenable routine. Port numbers of 0 to 15 will continue to be handled as a debug TAP number. Test TAPs will be port numbers of 16 to 31. This functionality will be needed for doing a flash mass erase on CC26xx/CC13xx targets. It is possible for user application to block even adding the Cortex M TAP to the scan chain, so the only way to unbrick the target and erase the flash is using a component on a test TAP of the device's ICEPick router. Change-Id: I0aa52a08d43a00cbd396efdeadd504fc31c98510 Signed-off-by: Edward Fewell Reviewed-on: http://openocd.zylin.com/5715 Tested-by: jenkins Reviewed-by: Antonio Borneo --- tcl/target/icepick.cfg | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tcl/target/icepick.cfg b/tcl/target/icepick.cfg index 36b0b7033..d1250711b 100644 --- a/tcl/target/icepick.cfg +++ b/tcl/target/icepick.cfg @@ -75,9 +75,22 @@ proc icepick_c_setup {jrc} { } # jrc == TAP name for the ICEpick -# port == a port number, 0..15 +# port == a port number, 0..15 for debug tap, 16..31 for test tap proc icepick_c_tapenable {jrc port} { + if { ($port >= 0) && ($port < 16) } { + # Debug tap" + set tap $port + set block 0x2 + } elseif { $port < 32 } { + # Test tap + set tap [expr ($port - 16)] + set block 0x1 + } else { + echo "ERROR: Invalid ICEPick C port number: $port" + return + } + # First CONNECT to the ICEPick # echo "Connecting to ICEPick" icepick_c_connect $jrc @@ -90,18 +103,18 @@ proc icepick_c_tapenable {jrc port} { # And never to enter RESET, which will disable the TAPs. # first enable power and clock for TAP - icepick_c_router $jrc 1 0x2 $port 0x110048 + icepick_c_router $jrc 1 $block $tap 0x110048 # TRM states that the register should be read back here, skipped for now # enable debug "default" mode - icepick_c_router $jrc 1 0x2 $port 0x112048 + icepick_c_router $jrc 1 $block $tap 0x112048 # TRM states that debug enable and debug mode should be read back and # confirmed - skipped for now # Finally select the tap - icepick_c_router $jrc 1 0x2 $port 0x112148 + icepick_c_router $jrc 1 $block $tap 0x112148 # Enter the bypass state irscan $jrc [CONST IR_BYPASS] -endstate RUN/IDLE @@ -119,6 +132,7 @@ proc icepick_d_set_core_control {jrc coreid value } { # Follow the sequence described in # http://processors.wiki.ti.com/images/f/f6/Router_Scan_Sequence-ICEpick-D.pdf proc icepick_d_tapenable {jrc port coreid { value 0x2008 } } { + # First CONNECT to the ICEPick icepick_c_connect $jrc icepick_c_setup $jrc From 5a79481d3b17c4134a43052cea9a7902bbf0accf Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sun, 26 Apr 2020 19:28:15 +0200 Subject: [PATCH 353/354] target/armv7m_trace: Calculate prescaler for external capture devices This fixes a regression introduced in "2dc88e1479f29ef0141b05bfcd907ad9a3e2d54c" Change-Id: I04dc19ed30118a4c499b83732700b2ee0fdb67b6 Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5610 Tested-by: jenkins Reviewed-by: Andreas Fritiofson --- src/jtag/drivers/jlink.c | 17 ++++++++++------- src/target/armv7m_trace.c | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c index 80202ed29..1baf3454e 100644 --- a/src/jtag/drivers/jlink.c +++ b/src/jtag/drivers/jlink.c @@ -1324,18 +1324,16 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t min_freq; uint32_t max_freq; + trace_enabled = enabled; + if (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SWO)) { + if (!enabled) + return ERROR_OK; + LOG_ERROR("Trace capturing is not supported by the device."); return ERROR_FAIL; } - if (pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART) { - LOG_ERROR("Selected pin protocol is not supported."); - return ERROR_FAIL; - } - - trace_enabled = enabled; - ret = jaylink_swo_stop(devh); if (ret != JAYLINK_OK) { @@ -1354,6 +1352,11 @@ static int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, return ERROR_OK; } + if (pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART) { + LOG_ERROR("Selected pin protocol is not supported."); + return ERROR_FAIL; + } + buffer_size = calculate_trace_buffer_size(); if (!buffer_size) { diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c index 853362f7e..6b368f7a0 100644 --- a/src/target/armv7m_trace.c +++ b/src/target/armv7m_trace.c @@ -68,6 +68,22 @@ int armv7m_trace_tpiu_config(struct target *target) if (retval != ERROR_OK) return retval; + if (trace_config->config_type == TRACE_CONFIG_TYPE_EXTERNAL) { + prescaler = trace_config->traceclkin_freq / trace_config->trace_freq; + + if (trace_config->traceclkin_freq % trace_config->trace_freq) { + prescaler++; + + int trace_freq = trace_config->traceclkin_freq / prescaler; + LOG_INFO("Can not obtain %u trace port frequency from %u " + "TRACECLKIN frequency, using %u instead", + trace_config->trace_freq, trace_config->traceclkin_freq, + trace_freq); + + trace_config->trace_freq = trace_freq; + } + } + if (!trace_config->trace_freq) { LOG_ERROR("Trace port frequency is 0, can't enable TPIU"); return ERROR_FAIL; From 8833c889da07eae750bcbc11215cc84323de9b74 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Sun, 14 Jun 2020 21:57:35 +0200 Subject: [PATCH 354/354] libjaylink: Update to latest Git version This update is for testing the upcoming 0.2.0 release. Change-Id: I400b09eb3ead4306c83c7980c621124101aaef7e Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5723 Tested-by: jenkins Reviewed-by: Paul Fertser --- src/jtag/drivers/libjaylink | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jtag/drivers/libjaylink b/src/jtag/drivers/libjaylink index f73ad5e66..dce11b89e 160000 --- a/src/jtag/drivers/libjaylink +++ b/src/jtag/drivers/libjaylink @@ -1 +1 @@ -Subproject commit f73ad5e667ae8b26a52b847c603fdadaabf302a6 +Subproject commit dce11b89e85179a92a0fe3a90d2693ca891ed646