Merge branch 'master' into from_upstream

Conflicts:
	doc/openocd.texi
	src/flash/nor/fespi.c

Change-Id: Iaac61cb6ab8bba9df1d4b9a52671a09163eb50b2
This commit is contained in:
Tim Newsome 2021-12-28 10:45:40 -08:00
commit cc0ecfb6d5
27 changed files with 548 additions and 241 deletions

View File

@ -154,7 +154,9 @@ 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}=="1020", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1051", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1055", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1061", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Raisonance RLink

View File

@ -1359,6 +1359,16 @@ Read the OpenOCD source code (and Developer's Guide)
if you have a new kind of hardware interface
and need to provide a driver for it.
@deffn {Command} {find} 'filename'
Prints full path to @var{filename} according to OpenOCD search rules.
@end deffn
@deffn {Command} {ocd_find} 'filename'
Prints full path to @var{filename} according to OpenOCD search rules. This
is a low level function used by the @command{find}. Usually you want
to use @command{find}, instead.
@end deffn
@section Board Config Files
@cindex config file, board
@cindex board config file
@ -2040,6 +2050,19 @@ may access or activate TAPs.
After it leaves this stage, configuration commands may no
longer be issued.
@deffn {Command} {command mode} [command_name]
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. (command valid any time)
In this document, the modes are described as stages, 'config' and
'exec' mode correspond configuration stage and run stage. 'any' means
the command can be executed in either
stages. @xref{configurationstage,,Configuration Stage}, and
@xref{enteringtherunstage,,Entering the Run Stage}.
@end deffn
@anchor{enteringtherunstage}
@section Entering the Run Stage
@ -2075,11 +2098,29 @@ If this command does not appear in any startup/configuration file
OpenOCD executes the command for you after processing all
configuration files and/or command line options.
@b{NOTE:} This command normally occurs at or near the end of your
@b{NOTE:} This command normally occurs near the end of your
openocd.cfg file to force OpenOCD to ``initialize'' and make the
targets ready. For example: If your openocd.cfg file needs to
read/write memory on your target, @command{init} must occur before
the memory read/write commands. This includes @command{nand probe}.
@command{init} calls the following internal OpenOCD commands to initialize
corresponding subsystems:
@deffn {Config Command} {target init}
@deffnx {Command} {transport init}
@deffnx {Command} {dap init}
@deffnx {Config Command} {flash init}
@deffnx {Config Command} {nand init}
@deffnx {Config Command} {pld init}
@deffnx {Command} {tpiu init}
@end deffn
@end deffn
@deffn {Config Command} {noinit}
Prevent OpenOCD from implicit @command{init} call at the end of startup.
Allows issuing configuration commands over telnet or Tcl connection.
When you are done with configuration use @command{init} to enter
the run stage.
@end deffn
@deffn {Overridable Procedure} {jtag_init}
@ -2447,6 +2488,16 @@ interface string or for user class interface.
@deffn {Command} {cmsis-dap info}
Display various device information, like hardware version, firmware version, current bus status.
@end deffn
@deffn {Command} {cmsis-dap cmd} number number ...
Execute an arbitrary CMSIS-DAP command. Use for adapter testing or for handling
of an adapter vendor specific command from a Tcl script.
Take given numbers as bytes, assemble a CMSIS-DAP protocol command packet
from them and send it to the adapter. The first 4 bytes of the adapter response
are logged.
See @url{https://arm-software.github.io/CMSIS_5/DAP/html/group__DAP__Commands__gr.html}
@end deffn
@end deffn
@deffn {Interface Driver} {dummy}
@ -3433,6 +3484,17 @@ Parameters are currently the same as "jtag newtap" but this is
expected to change.
@end deffn
@cindex SWD multi-drop
The newer SWD devices (SW-DP v2 or SWJ-DP v2) support the multi-drop extension
of SWD protocol: two or more devices can be connected to one SWD adapter.
SWD transport works in multi-drop mode if @ref{dap_create,DAP} is configured
with both @code{-dp-id} and @code{-instance-id} parameters regardless how many
DAPs are created.
Not all adapters and adapter drivers support SWD multi-drop. Only the following
adapter drivers are SWD multi-drop capable:
cmsis_dap (use an adapter with CMSIS-DAP version 2.0), ftdi, all bitbang based.
@subsection SPI Transport
@cindex SPI
@cindex Serial Peripheral Interface
@ -4346,6 +4408,7 @@ instead of "@option{-chain-position} @var{dotted.name}" when the target is creat
The @command{dap} command group supports the following sub-commands:
@anchor{dap_create}
@deffn {Command} {dap create} dap_name @option{-chain-position} dotted.name configparams...
Declare a DAP instance named @var{dap_name} linked to the JTAG tap
@var{dotted.name}. This also creates a new command (@command{dap_name})
@ -6172,6 +6235,21 @@ USER PAGE: 0xAEECFF80FE9A9239
All members of the ATSAMV7x, ATSAMS70, and ATSAME70 families from
Atmel include internal flash and use ARM's Cortex-M7 core.
This driver uses the same command names/syntax as @xref{at91sam3}.
@example
flash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME
@end example
@deffn {Command} {atsamv gpnvm} [@option{show} [@option{all}|number]]
@deffnx {Command} {atsamv gpnvm} (@option{clr}|@option{set}) number
With no parameters, @option{show} or @option{show all},
shows the status of all GPNVM bits.
With @option{show} @var{number}, displays that bit.
With @option{set} @var{number} or @option{clear} @var{number},
modifies that GPNVM bit.
@end deffn
@end deffn
@deffn {Flash Driver} {at91sam7}
@ -6802,9 +6880,11 @@ flash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME
@deffn {Flash Driver} {nrf5}
All members of the nRF51 microcontroller families from Nordic Semiconductor
include internal flash and use ARM Cortex-M0 core.
Also, the nRF52832 microcontroller from Nordic Semiconductor, which include
internal flash and use an ARM Cortex-M4F core.
include internal flash and use ARM Cortex-M0 core. nRF52 family powered
by ARM Cortex-M4 or M4F core is supported too. nRF52832 is fully supported
including BPROT flash protection scheme. nRF52833 and nRF52840 devices are
supported with the exception of security extensions (flash access control list
- ACL).
@example
flash bank $_FLASHNAME nrf5 0 0x00000000 0 0 $_TARGETNAME
@ -8211,6 +8291,13 @@ In most cases, no such restriction is listed; this indicates commands
which are only available after the configuration stage has completed.
@end deffn
@deffn {Command} {usage} [string]
With no parameters, prints usage text for all commands. Otherwise,
prints all usage text of which command, help text, and usage text
containing @var{string}.
Not every command provides helptext.
@end deffn
@deffn {Command} {sleep} msec [@option{busy}]
Wait for at least @var{msec} milliseconds before resuming.
If @option{busy} is passed, busy-wait instead of sleeping.
@ -8700,6 +8787,14 @@ Requests the current target to map the specified @var{virtual_address}
to its corresponding physical address, and displays the result.
@end deffn
@deffn {Command} {add_help_text} 'command_name' 'help-string'
Add or replace help text on the given @var{command_name}.
@end deffn
@deffn {Command} {add_usage_text} 'command_name' 'help-string'
Add or replace usage text on the given @var{command_name}.
@end deffn
@node Architecture and Core Commands
@chapter Architecture and Core Commands
@cindex Architecture Specific Commands
@ -10163,31 +10258,52 @@ argument is passed, the raw buffer is dumped in base64 format, so that
external tools can gather the data efficiently.
@end deffn
@deffn {Command} {riscv expose_csrs} n[-m|=name] [...]
@deffn {Config Command} {riscv expose_csrs} n[-m|=name] [...]
Configure which CSRs to expose in addition to the standard ones. The CSRs to expose
can be specified as individual register numbers or register ranges (inclusive). For the
individually listed CSRs, a human-readable name can optionally be set, which
will get csr_ prepended to it. If no name is provided, the register will be
named csr<n>.
This command must be executed before `init`.
individually listed CSRs, a human-readable name can optionally be set using the @code{n=name}
syntax, which will get @code{csr_} prepended to it. If no name is provided, the register will be
named @code{csr<n>}.
By default OpenOCD attempts to expose only CSRs that are mentioned in a spec,
and then only if the corresponding extension appears to be implemented. This
command can be used if OpenOCD gets this wrong, or a target implements custom
command can be used if OpenOCD gets this wrong, or if the target implements custom
CSRs.
@example
# Expose a single RISC-V CSR number 128 under the name "csr128":
$_TARGETNAME expose_csrs 128
# Expose multiple RISC-V CSRs 128..132 under names "csr128" through "csr132":
$_TARGETNAME expose_csrs 128-132
# Expose a single RISC-V CSR number 1996 under custom name "csr_myregister":
$_TARGETNAME expose_csrs 1996=myregister
@end example
@end deffn
@deffn {Command} {riscv expose_custom} n[-m|=name] [...]
@deffn {Config Command} {riscv expose_custom} n[-m|=name] [...]
The RISC-V Debug Specification allows targets to expose custom registers
through abstract commands. (See Section 3.5.1.1 in that document.) This command
configures individual registers or register ranges (inclusive) that shall be exposed.
Number 0 indicates the first custom register, whose abstract command number is 0xc000.
For individually listed registers, a human-readable name can be optionally provided,
which will get custom_ prepended to it. If no name is provided, the register will
be named custom<n>.
For individually listed registers, a human-readable name can be optionally provided
using the @code{n=name} syntax, which will get @code{custom_} prepended to it. If no
name is provided, the register will be named @code{custom<n>}.
This command must be executed before `init`.
@example
# Expose one RISC-V custom register with number 0xc010 (0xc000 + 16)
# under the name "custom16":
$_TARGETNAME expose_custom 16
# Expose a range of RISC-V custom registers with numbers 0xc010 .. 0xc018
# (0xc000+16 .. 0xc000+24) under the names "custom16" through "custom24":
$_TARGETNAME expose_custom 16-24
# Expose one RISC-V custom register with number 0xc020 (0xc000 + 32) under
# user-defined name "custom_myregister":
$_TARGETNAME expose_custom 32=myregister
@end example
@end deffn
@deffn {Command} {riscv memory_sample} bucket address|clear [size=4]
@ -10216,18 +10332,27 @@ Set the maximum time to wait for a hart to come out of reset after reset is
deasserted.
@end deffn
@deffn {Command} {riscv set_prefer_sba} on|off
@emph{DEPRECATED -- avoid using this.
Use the command @command{riscv set_mem_access} instead.}
When on, prefer to use System Bus Access to access memory. When off (default),
prefer to use the Program Buffer to access memory.
Abstract Memory Access will be used with the lowest priority.
@deffn {Command} {riscv set_scratch_ram} none|[address]
Set the address of 16 bytes of scratch RAM the debugger can use, or 'none'.
This is used to access 64-bit floating point registers on 32-bit targets.
@end deffn
@deffn Command {riscv set_mem_access} method1 [method2] [method3]
Specify which memory access methods shall be used, and in which order of priority.
Method can be one of: 'progbuf', 'sysbus' or 'abstract'. Default: all methods enabled, and in this order.
Specify which RISC-V memory access method(s) shall be used, and in which order
of priority. At least one method must be specified.
Available methods are:
@itemize
@item @code{progbuf} - Use RISC-V Debug Program Buffer to access memory.
@item @code{sysbus} - Access memory via RISC-V Debug System Bus interface.
@item @code{abstract} - Access memory via RISC-V Debug abstract commands.
@end itemize
By default, all memory access methods are enabled in the following order:
@code{progbuf sysbus abstract}.
This command can be used to change the memory access methods if the default
behavior is not suitable for a particular target.
@end deffn
@deffn {Command} {riscv set_enable_virtual} on|off

View File

@ -946,11 +946,6 @@ FLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command)
return ERROR_OK;
}
COMMAND_HANDLER(samd_handle_info_command)
{
return ERROR_OK;
}
COMMAND_HANDLER(samd_handle_chip_erase_command)
{
struct target *target = get_current_target(CMD_CTX);
@ -1211,14 +1206,6 @@ static const struct command_registration at91samd_exec_command_handlers[] = {
.help = "Deassert internal reset held by DSU.",
.usage = "",
},
{
.name = "info",
.handler = samd_handle_info_command,
.mode = COMMAND_EXEC,
.help = "Print information about the current at91samd chip "
"and its flash configuration.",
.usage = "",
},
{
.name = "chip-erase",
.handler = samd_handle_chip_erase_command,

View File

@ -140,8 +140,9 @@ static int cc26xx_init(struct flash_bank *bank)
return retval;
/* Check for working area to use for flash helper algorithm */
if (cc26xx_bank->working_area)
target_free_working_area(target, cc26xx_bank->working_area);
target_free_working_area(target, cc26xx_bank->working_area);
cc26xx_bank->working_area = NULL;
retval = target_alloc_working_area(target, cc26xx_bank->algo_working_size,
&cc26xx_bank->working_area);
if (retval != ERROR_OK)
@ -158,6 +159,7 @@ static int cc26xx_init(struct flash_bank *bank)
LOG_ERROR("%s: Failed to load flash helper algorithm",
cc26xx_bank->family_name);
target_free_working_area(target, cc26xx_bank->working_area);
cc26xx_bank->working_area = NULL;
return retval;
}
@ -172,6 +174,7 @@ static int cc26xx_init(struct flash_bank *bank)
LOG_ERROR("%s: Failed to start flash helper algorithm",
cc26xx_bank->family_name);
target_free_working_area(target, cc26xx_bank->working_area);
cc26xx_bank->working_area = NULL;
return retval;
}

View File

@ -1359,9 +1359,7 @@ static int cfi_intel_write_block(struct flash_bank *bank, const uint8_t *buffer,
/* free up resources */
cleanup:
if (source)
target_free_working_area(target, source);
target_free_working_area(target, source);
target_free_working_area(target, write_algorithm);
destroy_reg_param(&reg_params[0]);

View File

@ -523,7 +523,7 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
}
}
int xlen = riscv_xlen(target);
unsigned int xlen = riscv_xlen(target);
struct working_area *algorithm_wa = NULL;
struct working_area *data_wa = NULL;
const uint8_t *bin;
@ -547,19 +547,14 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
algorithm_wa = NULL;
} else {
data_wa_size = MIN(target->working_area_size - algorithm_wa->size, count);
while (1) {
if (data_wa_size < 128) {
LOG_WARNING("Couldn't allocate data working area.");
target_free_working_area(target, algorithm_wa);
algorithm_wa = NULL;
}
if (target_alloc_working_area_try(target, data_wa_size, &data_wa) ==
ERROR_OK) {
break;
}
data_wa_size = data_wa_size * 3 / 4;
data_wa_size = MIN(target_get_working_area_avail(target), count);
if (data_wa_size < 128) {
LOG_WARNING("Couldn't allocate data working area.");
target_free_working_area(target, algorithm_wa);
algorithm_wa = NULL;
} else if (target_alloc_working_area(target, data_wa_size, &data_wa) != ERROR_OK) {
target_free_working_area(target, algorithm_wa);
algorithm_wa = NULL;
}
}
} else {
@ -612,9 +607,9 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
goto err;
}
int algorithm_result = buf_get_u64(reg_params[0].value, 0, xlen);
uint64_t algorithm_result = buf_get_u64(reg_params[0].value, 0, xlen);
if (algorithm_result != 0) {
LOG_ERROR("Algorithm returned error %d", algorithm_result);
LOG_ERROR("Algorithm returned error %" PRId64, algorithm_result);
retval = ERROR_FAIL;
goto err;
}
@ -666,10 +661,8 @@ static int fespi_write(struct flash_bank *bank, const uint8_t *buffer,
return ERROR_OK;
err:
if (algorithm_wa) {
target_free_working_area(target, data_wa);
target_free_working_area(target, algorithm_wa);
}
target_free_working_area(target, data_wa);
target_free_working_area(target, algorithm_wa);
/* Switch to HW mode before return to prompt */
if (fespi_enable_hw_mode(bank) != ERROR_OK)

View File

@ -933,39 +933,6 @@ static int kinetis_ke_ftmrx_command(struct flash_bank *bank, uint8_t count,
return ERROR_OK;
}
COMMAND_HANDLER(kinetis_ke_securing_test)
{
int result;
struct target *target = get_current_target(CMD_CTX);
struct flash_bank *bank = NULL;
uint32_t address;
uint8_t FCCOBIX[2], FCCOBHI[2], FCCOBLO[2], fstat;
result = get_flash_bank_by_addr(target, 0x00000000, true, &bank);
if (result != ERROR_OK)
return result;
assert(bank);
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
address = bank->base + 0x00000400;
FCCOBIX[0] = 0;
FCCOBHI[0] = FTMRX_CMD_ERASESECTOR;
FCCOBLO[0] = address >> 16;
FCCOBIX[1] = 1;
FCCOBHI[1] = address >> 8;
FCCOBLO[1] = address;
return kinetis_ke_ftmrx_command(bank, 2, FCCOBIX, FCCOBHI, FCCOBLO, &fstat);
}
static int kinetis_ke_erase(struct flash_bank *bank, unsigned int first,
unsigned int last)
{
@ -1241,24 +1208,17 @@ static const struct command_registration kinetis_ke_security_command_handlers[]
{
.name = "check_security",
.mode = COMMAND_EXEC,
.help = "",
.help = "Check status of device security lock",
.usage = "",
.handler = kinetis_ke_check_flash_security_status,
},
{
.name = "mass_erase",
.mode = COMMAND_EXEC,
.help = "",
.help = "Issue a complete flash erase via the MDM-AP",
.usage = "",
.handler = kinetis_ke_mdm_mass_erase,
},
{
.name = "test_securing",
.mode = COMMAND_EXEC,
.help = "",
.usage = "",
.handler = kinetis_ke_securing_test,
},
COMMAND_REGISTRATION_DONE
};
@ -1266,7 +1226,7 @@ static const struct command_registration kinetis_ke_exec_command_handlers[] = {
{
.name = "mdm",
.mode = COMMAND_ANY,
.help = "",
.help = "MDM-AP command group",
.usage = "",
.chain = kinetis_ke_security_command_handlers,
},
@ -1284,7 +1244,7 @@ static const struct command_registration kinetis_ke_command_handler[] = {
{
.name = "kinetis_ke",
.mode = COMMAND_ANY,
.help = "Kinetis KE NAND flash controller commands",
.help = "Kinetis KE flash controller commands",
.usage = "",
.chain = kinetis_ke_exec_command_handlers,
},

View File

@ -335,8 +335,9 @@ static int msp432_init(struct flash_bank *bank)
}
/* Check for working area to use for flash helper algorithm */
if (msp432_bank->working_area)
target_free_working_area(target, msp432_bank->working_area);
target_free_working_area(target, msp432_bank->working_area);
msp432_bank->working_area = NULL;
retval = target_alloc_working_area(target, ALGO_WORKING_SIZE,
&msp432_bank->working_area);
if (retval != ERROR_OK)

View File

@ -80,10 +80,8 @@ static int npcx_init(struct flash_bank *bank)
struct npcx_flash_bank *npcx_bank = bank->driver_priv;
/* Check for working area to use for flash helper algorithm */
if (npcx_bank->working_area) {
target_free_working_area(target, npcx_bank->working_area);
npcx_bank->working_area = NULL;
}
target_free_working_area(target, npcx_bank->working_area);
npcx_bank->working_area = NULL;
int retval = target_alloc_working_area(target, npcx_bank->algo_working_size,
&npcx_bank->working_area);

View File

@ -182,10 +182,8 @@ destroy_rp_free_wa:
/* Something went wrong, do some cleanup */
destroy_reg_param(&reg_params);
if (g_stack_area) {
target_free_working_area(target, g_stack_area);
g_stack_area = NULL;
}
target_free_working_area(target, g_stack_area);
g_stack_area = NULL;
return hr;
}

View File

@ -703,11 +703,14 @@ static int sh_qspi_upload_helper(struct flash_bank *bank)
};
int ret;
if (info->source)
target_free_working_area(target, info->source);
if (info->io_algorithm)
target_free_working_area(target, info->io_algorithm);
target_free_working_area(target, info->source);
target_free_working_area(target, info->io_algorithm);
/* FIXME: Working areas are allocated during flash probe
* and eventual target_free_all_working_areas() called in case
* of target reset or run is not handled at all.
* Not a big problem if area backp is off.
*/
/* flash write code */
if (target_alloc_working_area(target, sizeof(sh_qspi_io_code),
&info->io_algorithm) != ERROR_OK) {

View File

@ -96,6 +96,7 @@ const struct flash_device flash_devices[] = {
FLASH_ID("micron n25q256 1.8v", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0019bb20, 0x100, 0x10000, 0x2000000),
FLASH_ID("micron mt25ql512", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0020ba20, 0x100, 0x10000, 0x4000000),
FLASH_ID("micron mt25ql01", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0021ba20, 0x100, 0x10000, 0x8000000),
FLASH_ID("micron mt25qu01", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0021bb20, 0x100, 0x10000, 0x8000000),
FLASH_ID("micron mt25ql02", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0022ba20, 0x100, 0x10000, 0x10000000),
FLASH_ID("micron mt25qu01", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0021bb20, 0x100, 0x10000, 0x8000000),
FLASH_ID("win w25q80bv", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001440ef, 0x100, 0x10000, 0x100000),

View File

@ -1145,6 +1145,7 @@ COMMAND_HANDLER(handle_sleep_command)
int64_t then = timeval_ms();
while (timeval_ms() - then < (int64_t)duration) {
target_call_timer_callbacks_now();
keep_alive();
usleep(1000);
}
} else

View File

@ -29,8 +29,26 @@ static int swclk_gpio = -1;
static int swdio_gpio = -1;
static int led_gpio = -1;
static int gpiochip = -1;
static int tck_gpiochip = -1;
static int tms_gpiochip = -1;
static int tdi_gpiochip = -1;
static int tdo_gpiochip = -1;
static int trst_gpiochip = -1;
static int srst_gpiochip = -1;
static int swclk_gpiochip = -1;
static int swdio_gpiochip = -1;
static int led_gpiochip = -1;
static struct gpiod_chip *gpiod_chip_tck;
static struct gpiod_chip *gpiod_chip_tms;
static struct gpiod_chip *gpiod_chip_tdi;
static struct gpiod_chip *gpiod_chip_tdo;
static struct gpiod_chip *gpiod_chip_trst;
static struct gpiod_chip *gpiod_chip_srst;
static struct gpiod_chip *gpiod_chip_swclk;
static struct gpiod_chip *gpiod_chip_swdio;
static struct gpiod_chip *gpiod_chip_led;
static struct gpiod_chip *gpiod_chip;
static struct gpiod_line *gpiod_tck;
static struct gpiod_line *gpiod_tms;
static struct gpiod_line *gpiod_tdi;
@ -273,12 +291,31 @@ static int linuxgpiod_quit(void)
helper_release(gpiod_tdi);
helper_release(gpiod_tdo);
gpiod_chip_close(gpiod_chip);
if (gpiod_chip_led != NULL)
gpiod_chip_close(gpiod_chip_led);
if (gpiod_chip_srst != NULL)
gpiod_chip_close(gpiod_chip_srst);
if (gpiod_chip_swdio != NULL)
gpiod_chip_close(gpiod_chip_swdio);
if (gpiod_chip_swclk != NULL)
gpiod_chip_close(gpiod_chip_swclk);
if (gpiod_chip_trst != NULL)
gpiod_chip_close(gpiod_chip_trst);
if (gpiod_chip_tms != NULL)
gpiod_chip_close(gpiod_chip_tms);
if (gpiod_chip_tck != NULL)
gpiod_chip_close(gpiod_chip_tck);
if (gpiod_chip_tdi != NULL)
gpiod_chip_close(gpiod_chip_tdi);
if (gpiod_chip_tdo != NULL)
gpiod_chip_close(gpiod_chip_tdo);
return ERROR_OK;
}
static struct gpiod_line *helper_get_line(const char *label, unsigned int offset, int val, int dir, int flags)
static struct gpiod_line *helper_get_line(const char *label,
struct gpiod_chip *gpiod_chip, unsigned int offset,
int val, int dir, int flags)
{
struct gpiod_line *line;
int retval;
@ -304,19 +341,25 @@ static struct gpiod_line *helper_get_line(const char *label, unsigned int offset
return line;
}
static struct gpiod_line *helper_get_input_line(const char *label, unsigned int offset)
static struct gpiod_line *helper_get_input_line(const char *label,
struct gpiod_chip *gpiod_chip, unsigned int offset)
{
return helper_get_line(label, offset, 0, GPIOD_LINE_REQUEST_DIRECTION_INPUT, 0);
return helper_get_line(label, gpiod_chip, offset, 0,
GPIOD_LINE_REQUEST_DIRECTION_INPUT, 0);
}
static struct gpiod_line *helper_get_output_line(const char *label, unsigned int offset, int val)
static struct gpiod_line *helper_get_output_line(const char *label,
struct gpiod_chip *gpiod_chip, unsigned int offset, int val)
{
return helper_get_line(label, offset, val, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0);
return helper_get_line(label, gpiod_chip, offset, val,
GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, 0);
}
static struct gpiod_line *helper_get_open_drain_output_line(const char *label, unsigned int offset, int val)
static struct gpiod_line *helper_get_open_drain_output_line(const char *label,
struct gpiod_chip *gpiod_chip, unsigned int offset, int val)
{
return helper_get_line(label, offset, val, GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN);
return helper_get_line(label, gpiod_chip, offset, val,
GPIOD_LINE_REQUEST_DIRECTION_OUTPUT, GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN);
}
static int linuxgpiod_init(void)
@ -325,12 +368,6 @@ static int linuxgpiod_init(void)
bitbang_interface = &linuxgpiod_bitbang;
gpiod_chip = gpiod_chip_open_by_number(gpiochip);
if (!gpiod_chip) {
LOG_ERROR("Cannot open LinuxGPIOD gpiochip %d", gpiochip);
return ERROR_JTAG_INIT_FAILED;
}
/*
* Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST
* as outputs. Drive TDI and TCK low, and TMS/TRST/SRST high.
@ -343,27 +380,54 @@ static int linuxgpiod_init(void)
goto out_error;
}
gpiod_tdo = helper_get_input_line("tdo", tdo_gpio);
gpiod_chip_tdo = gpiod_chip_open_by_number(tdo_gpiochip);
if (!gpiod_chip_tdo) {
LOG_ERROR("Cannot open LinuxGPIOD tdo_gpiochip %d", tdo_gpiochip);
goto out_error;
}
gpiod_chip_tdi = gpiod_chip_open_by_number(tdi_gpiochip);
if (!gpiod_chip_tdi) {
LOG_ERROR("Cannot open LinuxGPIOD tdi_gpiochip %d", tdi_gpiochip);
goto out_error;
}
gpiod_chip_tck = gpiod_chip_open_by_number(tck_gpiochip);
if (!gpiod_chip_tck) {
LOG_ERROR("Cannot open LinuxGPIOD tck_gpiochip %d", tck_gpiochip);
goto out_error;
}
gpiod_chip_tms = gpiod_chip_open_by_number(tms_gpiochip);
if (!gpiod_chip_tms) {
LOG_ERROR("Cannot open LinuxGPIOD tms_gpiochip %d", tms_gpiochip);
goto out_error;
}
gpiod_tdo = helper_get_input_line("tdo", gpiod_chip_tdo, tdo_gpio);
if (!gpiod_tdo)
goto out_error;
gpiod_tdi = helper_get_output_line("tdi", tdi_gpio, 0);
gpiod_tdi = helper_get_output_line("tdi", gpiod_chip_tdi, tdi_gpio, 0);
if (!gpiod_tdi)
goto out_error;
gpiod_tck = helper_get_output_line("tck", tck_gpio, 0);
gpiod_tck = helper_get_output_line("tck", gpiod_chip_tck, tck_gpio, 0);
if (!gpiod_tck)
goto out_error;
gpiod_tms = helper_get_output_line("tms", tms_gpio, 1);
gpiod_tms = helper_get_output_line("tms", gpiod_chip_tms, tms_gpio, 1);
if (!gpiod_tms)
goto out_error;
if (is_gpio_valid(trst_gpio)) {
gpiod_chip_trst = gpiod_chip_open_by_number(trst_gpiochip);
if (!gpiod_chip_trst) {
LOG_ERROR("Cannot open LinuxGPIOD trst_gpiochip %d", trst_gpiochip);
goto out_error;
}
if (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN)
gpiod_trst = helper_get_open_drain_output_line("trst", trst_gpio, 1);
gpiod_trst = helper_get_open_drain_output_line("trst", gpiod_chip_trst, trst_gpio, 1);
else
gpiod_trst = helper_get_output_line("trst", trst_gpio, 1);
gpiod_trst = helper_get_output_line("trst", gpiod_chip_trst, trst_gpio, 1);
if (!gpiod_trst)
goto out_error;
@ -376,27 +440,50 @@ static int linuxgpiod_init(void)
goto out_error;
}
gpiod_swclk = helper_get_output_line("swclk", swclk_gpio, 1);
gpiod_chip_swclk = gpiod_chip_open_by_number(swclk_gpiochip);
if (!gpiod_chip_swclk) {
LOG_ERROR("Cannot open LinuxGPIOD swclk_gpiochip %d", swclk_gpiochip);
goto out_error;
}
gpiod_chip_swdio = gpiod_chip_open_by_number(swdio_gpiochip);
if (!gpiod_chip_swdio) {
LOG_ERROR("Cannot open LinuxGPIOD swdio_gpiochip %d", swdio_gpiochip);
goto out_error;
}
gpiod_swclk = helper_get_output_line("swclk", gpiod_chip_swclk, swclk_gpio, 1);
if (!gpiod_swclk)
goto out_error;
gpiod_swdio = helper_get_output_line("swdio", swdio_gpio, 1);
gpiod_swdio = helper_get_output_line("swdio", gpiod_chip_swdio, swdio_gpio, 1);
if (!gpiod_swdio)
goto out_error;
}
if (is_gpio_valid(srst_gpio)) {
gpiod_chip_srst = gpiod_chip_open_by_number(srst_gpiochip);
if (!gpiod_chip_srst) {
LOG_ERROR("Cannot open LinuxGPIOD srst_gpiochip %d", srst_gpiochip);
goto out_error;
}
if (jtag_get_reset_config() & RESET_SRST_PUSH_PULL)
gpiod_srst = helper_get_output_line("srst", srst_gpio, 1);
gpiod_srst = helper_get_output_line("srst", gpiod_chip_srst, srst_gpio, 1);
else
gpiod_srst = helper_get_open_drain_output_line("srst", srst_gpio, 1);
gpiod_srst = helper_get_open_drain_output_line("srst", gpiod_chip_srst, srst_gpio, 1);
if (!gpiod_srst)
goto out_error;
}
if (is_gpio_valid(led_gpio)) {
gpiod_led = helper_get_output_line("led", led_gpio, 0);
gpiod_chip_led = gpiod_chip_open_by_number(led_gpiochip);
if (!gpiod_chip_led) {
LOG_ERROR("Cannot open LinuxGPIOD led_gpiochip %d", led_gpiochip);
goto out_error;
}
gpiod_led = helper_get_output_line("led", gpiod_chip_led, led_gpio, 0);
if (!gpiod_led)
goto out_error;
}
@ -409,6 +496,21 @@ out_error:
return ERROR_JTAG_INIT_FAILED;
}
COMMAND_HELPER(linuxgpiod_helper_gpionum, const char *name, int *chip, int *line)
{
int i = 0;
if (CMD_ARGC > 2)
return ERROR_COMMAND_SYNTAX_ERROR;
if (CMD_ARGC == 2) {
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], *chip);
i = 1;
}
if (CMD_ARGC > 0)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[i], *line);
command_print(CMD, "LinuxGPIOD %s: chip = %d, num = %d", name, *chip, *line);
return ERROR_OK;
}
COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionums)
{
if (CMD_ARGC == 4) {
@ -429,56 +531,38 @@ COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionums)
COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tck)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);
command_print(CMD, "LinuxGPIOD num: tck = %d", tck_gpio);
return ERROR_OK;
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tck", &tck_gpiochip,
&tck_gpio);
}
COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tms)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);
command_print(CMD, "LinuxGPIOD num: tms = %d", tms_gpio);
return ERROR_OK;
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tms", &tms_gpiochip,
&tms_gpio);
}
COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdo)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);
command_print(CMD, "LinuxGPIOD num: tdo = %d", tdo_gpio);
return ERROR_OK;
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdo", &tdo_gpiochip,
&tdo_gpio);
}
COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_tdi)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);
command_print(CMD, "LinuxGPIOD num: tdi = %d", tdi_gpio);
return ERROR_OK;
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "tdi", &tdi_gpiochip,
&tdi_gpio);
}
COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_srst)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);
command_print(CMD, "LinuxGPIOD num: srst = %d", srst_gpio);
return ERROR_OK;
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "srst", &srst_gpiochip,
&srst_gpio);
}
COMMAND_HANDLER(linuxgpiod_handle_jtag_gpionum_trst)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);
command_print(CMD, "LinuxGPIOD num: trst = %d", trst_gpio);
return ERROR_OK;
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "trst", &trst_gpiochip,
&trst_gpio);
}
COMMAND_HANDLER(linuxgpiod_handle_swd_gpionums)
@ -499,35 +583,36 @@ COMMAND_HANDLER(linuxgpiod_handle_swd_gpionums)
COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swclk)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);
command_print(CMD, "LinuxGPIOD num: swclk = %d", swclk_gpio);
return ERROR_OK;
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swclk", &swclk_gpiochip,
&swclk_gpio);
}
COMMAND_HANDLER(linuxgpiod_handle_swd_gpionum_swdio)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio);
command_print(CMD, "LinuxGPIOD num: swdio = %d", swdio_gpio);
return ERROR_OK;
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "swdio", &swdio_gpiochip,
&swdio_gpio);
}
COMMAND_HANDLER(linuxgpiod_handle_gpionum_led)
{
if (CMD_ARGC == 1)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], led_gpio);
command_print(CMD, "LinuxGPIOD num: led = %d", led_gpio);
return ERROR_OK;
return CALL_COMMAND_HANDLER(linuxgpiod_helper_gpionum, "led", &led_gpiochip,
&led_gpio);
}
COMMAND_HANDLER(linuxgpiod_handle_gpiochip)
{
if (CMD_ARGC == 1)
if (CMD_ARGC == 1) {
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], gpiochip);
tck_gpiochip = gpiochip;
tms_gpiochip = gpiochip;
tdi_gpiochip = gpiochip;
tdo_gpiochip = gpiochip;
trst_gpiochip = gpiochip;
srst_gpiochip = gpiochip;
swclk_gpiochip = gpiochip;
swdio_gpiochip = gpiochip;
led_gpiochip = gpiochip;
}
command_print(CMD, "LinuxGPIOD gpiochip = %d", gpiochip);
return ERROR_OK;
@ -545,43 +630,43 @@ static const struct command_registration linuxgpiod_subcommand_handlers[] = {
.name = "tck_num",
.handler = linuxgpiod_handle_jtag_gpionum_tck,
.mode = COMMAND_CONFIG,
.help = "gpio number for tck.",
.usage = "tck",
.help = "gpio chip number (optional) and gpio number for tck.",
.usage = "[chip] tck",
},
{
.name = "tms_num",
.handler = linuxgpiod_handle_jtag_gpionum_tms,
.mode = COMMAND_CONFIG,
.help = "gpio number for tms.",
.usage = "tms",
.help = "gpio chip number (optional) and gpio number for tms.",
.usage = "[chip] tms",
},
{
.name = "tdo_num",
.handler = linuxgpiod_handle_jtag_gpionum_tdo,
.mode = COMMAND_CONFIG,
.help = "gpio number for tdo.",
.usage = "tdo",
.help = "gpio chip number (optional) and gpio number for tdo.",
.usage = "[chip] tdo",
},
{
.name = "tdi_num",
.handler = linuxgpiod_handle_jtag_gpionum_tdi,
.mode = COMMAND_CONFIG,
.help = "gpio number for tdi.",
.usage = "tdi",
.help = "gpio chip number (optional) and gpio number for tdi.",
.usage = "[chip] tdi",
},
{
.name = "srst_num",
.handler = linuxgpiod_handle_jtag_gpionum_srst,
.mode = COMMAND_CONFIG,
.help = "gpio number for srst.",
.usage = "srst",
.help = "gpio chip number (optional) and gpio number for srst.",
.usage = "[chip] srst",
},
{
.name = "trst_num",
.handler = linuxgpiod_handle_jtag_gpionum_trst,
.mode = COMMAND_CONFIG,
.help = "gpio number for trst.",
.usage = "trst",
.help = "gpio chip number (optional) and gpio number for trst.",
.usage = "[chip] trst",
},
{
.name = "swd_nums",
@ -594,22 +679,22 @@ static const struct command_registration linuxgpiod_subcommand_handlers[] = {
.name = "swclk_num",
.handler = linuxgpiod_handle_swd_gpionum_swclk,
.mode = COMMAND_CONFIG,
.help = "gpio number for swclk.",
.usage = "swclk",
.help = "gpio chip number (optional) and gpio number for swclk.",
.usage = "[chip] swclk",
},
{
.name = "swdio_num",
.handler = linuxgpiod_handle_swd_gpionum_swdio,
.mode = COMMAND_CONFIG,
.help = "gpio number for swdio.",
.usage = "swdio",
.help = "gpio chip number (optional) and gpio number for swdio.",
.usage = "[chip] swdio",
},
{
.name = "led_num",
.handler = linuxgpiod_handle_gpionum_led,
.mode = COMMAND_CONFIG,
.help = "gpio number for LED.",
.usage = "led",
.help = "gpio chip number (optional) and gpio number for LED.",
.usage = "[chip] led",
},
{
.name = "gpiochip",

View File

@ -273,6 +273,7 @@ static int vsllink_quit(void)
vsllink_free_buffer();
vsllink_usb_close(vsllink_handle);
libusb_exit(vsllink_handle->libusb_ctx);
free(vsllink_handle);
return ERROR_OK;

View File

@ -227,6 +227,7 @@ static int gdb_get_char_inner(struct connection *connection, int *next_char)
if (gdb_con->buf_cnt > 0)
break;
if (gdb_con->buf_cnt == 0) {
LOG_DEBUG("GDB connection closed by the remote client");
gdb_con->closed = true;
return ERROR_SERVER_REMOTE_CLOSED;
}
@ -348,11 +349,15 @@ static int gdb_putback_char(struct connection *connection, int last_char)
static int gdb_write(struct connection *connection, void *data, int len)
{
struct gdb_connection *gdb_con = connection->priv;
if (gdb_con->closed)
if (gdb_con->closed) {
LOG_DEBUG("GDB socket marked as closed, cannot write to it.");
return ERROR_SERVER_REMOTE_CLOSED;
}
if (connection_write(connection, data, len) == len)
return ERROR_OK;
LOG_WARNING("Error writing to GDB socket. Dropping the connection.");
gdb_con->closed = true;
return ERROR_SERVER_REMOTE_CLOSED;
}
@ -1003,16 +1008,19 @@ static int gdb_new_connection(struct connection *connection)
breakpoint_clear_target(target);
watchpoint_clear_target(target);
/* remove the initial ACK from the incoming buffer */
/* Since version 3.95 (gdb-19990504), with the exclusion of 6.5~6.8, GDB
* sends an ACK at connection with the following comment in its source code:
* "Ack any packet which the remote side has already sent."
* LLDB does the same since the first gdb-remote implementation.
* Remove the initial ACK from the incoming buffer.
*/
retval = gdb_get_char(connection, &initial_ack);
if (retval != ERROR_OK)
return retval;
/* FIX!!!??? would we actually ever receive a + here???
* Not observed.
*/
if (initial_ack != '+')
gdb_putback_char(connection, initial_ack);
target_call_event_callbacks(target, TARGET_EVENT_GDB_ATTACH);
if (target->rtos) {
@ -1353,7 +1361,7 @@ static int gdb_get_register_packet(struct connection *connection,
return gdb_error(connection, retval);
if (reg_list_size <= reg_num) {
LOG_ERROR("gdb requested a non-existing register");
LOG_ERROR("gdb requested a non-existing register (reg_num=%d)", reg_num);
return ERROR_SERVER_REMOTE_CLOSED;
}
@ -1415,7 +1423,7 @@ static int gdb_set_register_packet(struct connection *connection,
}
if (reg_list_size <= reg_num) {
LOG_ERROR("gdb requested a non-existing register");
LOG_ERROR("gdb requested a non-existing register (reg_num=%d)", reg_num);
free(bin_buf);
free(reg_list);
return ERROR_SERVER_REMOTE_CLOSED;

View File

@ -315,7 +315,12 @@ static int swd_connect_single(struct adiv5_dap *dap)
int64_t timeout = timeval_ms() + 500;
do {
swd_send_sequence(dap, JTAG_TO_SWD);
if (dap->switch_through_dormant) {
swd_send_sequence(dap, JTAG_TO_DORMANT);
swd_send_sequence(dap, DORMANT_TO_SWD);
} else {
swd_send_sequence(dap, JTAG_TO_SWD);
}
/* Clear link state, including the SELECT cache. */
dap->do_reconnect = false;
@ -330,6 +335,7 @@ static int swd_connect_single(struct adiv5_dap *dap)
alive_sleep(1);
dap->switch_through_dormant = !dap->switch_through_dormant;
} while (timeval_ms() < timeout);
if (retval != ERROR_OK) {
@ -568,7 +574,12 @@ static void swd_quit(struct adiv5_dap *dap)
* swd->switch_seq(DORMANT_TO_JTAG);
*/
} else {
swd->switch_seq(SWD_TO_JTAG);
if (dap->switch_through_dormant) {
swd->switch_seq(SWD_TO_DORMANT);
swd->switch_seq(DORMANT_TO_JTAG);
} else {
swd->switch_seq(SWD_TO_JTAG);
}
}
/* flush the queue to shift out the sequence before exit */

View File

@ -342,6 +342,11 @@ struct adiv5_dap {
bool multidrop_dp_id_valid;
/** TINSTANCE field of multidrop_targetsel has been configured */
bool multidrop_instance_id_valid;
/**
* Record if enter in SWD required passing through DORMANT
*/
bool switch_through_dormant;
};
/**

View File

@ -23,6 +23,7 @@
#define OPENOCD_TARGET_ARM_JTAG_H
#include <jtag/jtag.h>
#include <helper/bits.h>
struct arm_jtag {
struct jtag_tap *tap;
@ -42,7 +43,7 @@ static inline int arm_jtag_set_instr(struct jtag_tap *tap,
uint32_t new_instr, void *no_verify_capture, tap_state_t end_state)
{
/* inline most common code path */
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (new_instr & (BIT(tap->ir_length) - 1)))
return arm_jtag_set_instr_inner(tap, new_instr, no_verify_capture, end_state);
return ERROR_OK;

View File

@ -397,11 +397,9 @@ static int cortex_m_store_core_reg_u32(struct target *target,
/* check if value is written into register */
then = timeval_ms();
while (1) {
retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
&cortex_m->dcb_dhcsr);
retval = cortex_m_read_dhcsr_atomic_sticky(target);
if (retval != ERROR_OK)
return retval;
cortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr);
if (cortex_m->dcb_dhcsr & S_REGRDY)
break;
if (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) {
@ -2292,7 +2290,6 @@ int cortex_m_examine(struct target *target)
armv7m->debug_ap = dap_ap(swjdp, cortex_m->apsel);
}
/* Leave (only) generic DAP stuff for debugport_init(); */
armv7m->debug_ap->memaccess_tck = 8;
retval = mem_ap_init(armv7m->debug_ap);

View File

@ -1194,10 +1194,7 @@ static int scratch_reserve(struct target *target,
static int scratch_release(struct target *target,
scratch_mem_t *scratch)
{
if (scratch->area)
return target_free_working_area(target, scratch->area);
return ERROR_OK;
return target_free_working_area(target, scratch->area);
}
static int scratch_read64(struct target *target, scratch_mem_t *scratch,

View File

@ -1474,7 +1474,7 @@ static void semihosting_set_field(struct target *target, uint64_t value,
/* -------------------------------------------------------------------------
* Common semihosting commands handlers. */
static __COMMAND_HANDLER(handle_common_semihosting_command)
COMMAND_HANDLER(handle_common_semihosting_command)
{
struct target *target = get_current_target(CMD_CTX);
@ -1515,7 +1515,7 @@ static __COMMAND_HANDLER(handle_common_semihosting_command)
return ERROR_OK;
}
static __COMMAND_HANDLER(handle_common_semihosting_fileio_command)
COMMAND_HANDLER(handle_common_semihosting_fileio_command)
{
struct target *target = get_current_target(CMD_CTX);
@ -1545,7 +1545,7 @@ static __COMMAND_HANDLER(handle_common_semihosting_fileio_command)
return ERROR_OK;
}
static __COMMAND_HANDLER(handle_common_semihosting_cmdline)
COMMAND_HANDLER(handle_common_semihosting_cmdline)
{
struct target *target = get_current_target(CMD_CTX);
unsigned int i;
@ -1578,7 +1578,7 @@ static __COMMAND_HANDLER(handle_common_semihosting_cmdline)
return ERROR_OK;
}
static __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)
COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)
{
struct target *target = get_current_target(CMD_CTX);

View File

@ -2157,11 +2157,10 @@ static int target_restore_working_area(struct target *target, struct working_are
/* Restore the area's backup memory, if any, and return the area to the allocation pool */
static int target_free_working_area_restore(struct target *target, struct working_area *area, int restore)
{
if (!area || area->free)
return ERROR_OK;
int retval = ERROR_OK;
if (area->free)
return retval;
if (restore) {
retval = target_restore_working_area(target, area);
/* REVISIT: Perhaps the area should be freed even if restoring fails. */
@ -2540,6 +2539,10 @@ int target_checksum_memory(struct target *target, target_addr_t address, uint32_
LOG_ERROR("Target not examined yet");
return ERROR_FAIL;
}
if (!target->type->checksum_memory) {
LOG_ERROR("Target %s doesn't support checksum_memory", target_name(target));
return ERROR_FAIL;
}
retval = target->type->checksum_memory(target, address, size, &checksum);
if (retval != ERROR_OK) {
@ -6408,8 +6411,7 @@ next:
out:
free(test_pattern);
if (wa)
target_free_working_area(target, wa);
target_free_working_area(target, wa);
/* Test writes */
num_bytes = test_size + 4 + 4 + 4;
@ -6493,8 +6495,7 @@ nextw:
free(test_pattern);
if (wa)
target_free_working_area(target, wa);
target_free_working_area(target, wa);
return retval;
}

View File

@ -726,6 +726,13 @@ int target_alloc_working_area(struct target *target,
*/
int target_alloc_working_area_try(struct target *target,
uint32_t size, struct working_area **area);
/**
* Free a working area.
* Restore target data if area backup is configured.
* @param target
* @param area Pointer to the area to be freed or NULL
* @returns ERROR_OK if successful; error code if restore failed
*/
int target_free_working_area(struct target *target, struct working_area *area);
void target_free_all_working_areas(struct target *target);
uint32_t target_get_working_area_avail(struct target *target);

View File

@ -0,0 +1,14 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Microchip SAME51 Curiosity Nano evaluation kit.
#
# https://www.microchip.com/en-us/development-tool/EV76S68A
#
source [find interface/cmsis-dap.cfg]
set CHIPNAME same51
source [find target/atsame5x.cfg]
reset_config srst_only

View File

@ -0,0 +1,10 @@
# board MB1635x
# http://www.st.com/en/evaluation-tools/stm32mp135f-dk.html
source [find interface/stlink-dap.cfg]
transport select dapdirect_swd
source [find target/stm32mp13x.cfg]
reset_config srst_only

100
tcl/target/stm32mp13x.cfg Normal file
View File

@ -0,0 +1,100 @@
# STMicroelectronics STM32MP13x (Single Cortex-A7)
# http://www.st.com/stm32mp1
# HLA does not support 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/stm32mp13x_dk.cfg\"."
shutdown
}
source [find target/swj-dp.tcl]
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32mp13x
}
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 0x06501041
}
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
# 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.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0
target create $_CHIPNAME.cpu cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000
$_CHIPNAME.cpu cortex_a maskisr on
$_CHIPNAME.cpu cortex_a dacrfixup on
# interface does not work while srst is asserted
# this is target specific, valid for every board
# srst resets 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 {} {
# keep clock enabled in low-power
## catch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000004}
# freeze watchdog 1 and 2 on core halted
catch {$::_CHIPNAME.ap1 mww 0xe008102c 0x00000004}
catch {$::_CHIPNAME.ap1 mww 0xe008104c 0x00000008}
}
proc toggle_cpu_dbg_claim0 {} {
# toggle CPU0 DBG_CLAIM[0]
$::_CHIPNAME.ap1 mww 0xe00d0fa0 1
$::_CHIPNAME.ap1 mww 0xe00d0fa4 1
}
# FIXME: most of handlers below will be removed once reset framework get merged
$_CHIPNAME.ap1 configure -event reset-deassert-pre {
adapter deassert srst deassert trst
catch {dap init}
catch {$::_CHIPNAME.dap apid 1}
}
$_CHIPNAME.cpu configure -event reset-deassert-pre {$::_CHIPNAME.cpu arp_examine}
$_CHIPNAME.cpu configure -event reset-deassert-post {toggle_cpu_dbg_claim0; dbgmcu_enable_debug}
$_CHIPNAME.ap1 configure -event examine-start {dap init}
$_CHIPNAME.ap1 configure -event examine-end {dbgmcu_enable_debug}