You can subscribe to this list here.
| 2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(75) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2009 |
Jan
(70) |
Feb
(20) |
Mar
(52) |
Apr
(149) |
May
(387) |
Jun
(466) |
Jul
(133) |
Aug
(87) |
Sep
(122) |
Oct
(140) |
Nov
(185) |
Dec
(105) |
| 2010 |
Jan
(85) |
Feb
(45) |
Mar
(75) |
Apr
(17) |
May
(41) |
Jun
(52) |
Jul
(33) |
Aug
(29) |
Sep
(36) |
Oct
(15) |
Nov
(26) |
Dec
(34) |
| 2011 |
Jan
(26) |
Feb
(25) |
Mar
(26) |
Apr
(29) |
May
(20) |
Jun
(27) |
Jul
(15) |
Aug
(32) |
Sep
(13) |
Oct
(64) |
Nov
(60) |
Dec
(10) |
| 2012 |
Jan
(64) |
Feb
(63) |
Mar
(39) |
Apr
(43) |
May
(54) |
Jun
(11) |
Jul
(30) |
Aug
(45) |
Sep
(11) |
Oct
(70) |
Nov
(24) |
Dec
(23) |
| 2013 |
Jan
(17) |
Feb
(8) |
Mar
(35) |
Apr
(40) |
May
(20) |
Jun
(24) |
Jul
(36) |
Aug
(25) |
Sep
(42) |
Oct
(40) |
Nov
(9) |
Dec
(21) |
| 2014 |
Jan
(29) |
Feb
(24) |
Mar
(60) |
Apr
(22) |
May
(22) |
Jun
(46) |
Jul
(11) |
Aug
(23) |
Sep
(26) |
Oct
(10) |
Nov
(14) |
Dec
(2) |
| 2015 |
Jan
(28) |
Feb
(47) |
Mar
(33) |
Apr
(58) |
May
(5) |
Jun
(1) |
Jul
|
Aug
(8) |
Sep
(12) |
Oct
(25) |
Nov
(58) |
Dec
(21) |
| 2016 |
Jan
(12) |
Feb
(40) |
Mar
(2) |
Apr
(1) |
May
(67) |
Jun
(2) |
Jul
(5) |
Aug
(36) |
Sep
|
Oct
(24) |
Nov
(17) |
Dec
(50) |
| 2017 |
Jan
(14) |
Feb
(16) |
Mar
(2) |
Apr
(35) |
May
(14) |
Jun
(16) |
Jul
(3) |
Aug
(3) |
Sep
|
Oct
(19) |
Nov
|
Dec
(16) |
| 2018 |
Jan
(55) |
Feb
(11) |
Mar
(34) |
Apr
(14) |
May
(4) |
Jun
(20) |
Jul
(39) |
Aug
(16) |
Sep
(17) |
Oct
(16) |
Nov
(20) |
Dec
(30) |
| 2019 |
Jan
(29) |
Feb
(24) |
Mar
(37) |
Apr
(26) |
May
(19) |
Jun
(21) |
Jul
(2) |
Aug
(3) |
Sep
(9) |
Oct
(12) |
Nov
(12) |
Dec
(12) |
| 2020 |
Jan
(47) |
Feb
(36) |
Mar
(54) |
Apr
(44) |
May
(37) |
Jun
(19) |
Jul
(32) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(32) |
Dec
(11) |
| 2021 |
Jan
(14) |
Feb
(5) |
Mar
(40) |
Apr
(32) |
May
(42) |
Jun
(31) |
Jul
(29) |
Aug
(47) |
Sep
(38) |
Oct
(17) |
Nov
(74) |
Dec
(33) |
| 2022 |
Jan
(11) |
Feb
(15) |
Mar
(40) |
Apr
(21) |
May
(39) |
Jun
(44) |
Jul
(19) |
Aug
(46) |
Sep
(79) |
Oct
(35) |
Nov
(21) |
Dec
(15) |
| 2023 |
Jan
(56) |
Feb
(13) |
Mar
(43) |
Apr
(28) |
May
(60) |
Jun
(15) |
Jul
(29) |
Aug
(28) |
Sep
(32) |
Oct
(21) |
Nov
(42) |
Dec
(39) |
| 2024 |
Jan
(35) |
Feb
(17) |
Mar
(28) |
Apr
(7) |
May
(14) |
Jun
(35) |
Jul
(30) |
Aug
(35) |
Sep
(30) |
Oct
(28) |
Nov
(38) |
Dec
(18) |
| 2025 |
Jan
(21) |
Feb
(28) |
Mar
(36) |
Apr
(35) |
May
(34) |
Jun
(58) |
Jul
(9) |
Aug
(54) |
Sep
(47) |
Oct
(15) |
Nov
(42) |
Dec
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-12 20:15:35
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 5754aebc49450cc0da5c8a90ebd059160d21f256 (commit)
from ab22b0bf8f23924d8c76d3affd9e11528ba18438 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 5754aebc49450cc0da5c8a90ebd059160d21f256
Author: Bernhard Rosenkränzer <be...@ba...>
Date: Tue May 6 01:20:22 2025 +0200
target: riscv: Sync with the RISC-V fork
Regenerate autogenerated debug_defines.{c,h} files from current
riscv-debug-spec, sync remaining RISC-V target files with the
RISC-V fork.
This is based on the work of (in alphabetic order):
Aleksey Lotosh <lo...@gm...>
Alexander Rumyantsev <cet...@gm...>
Anastasiya Chernikova <ana...@sy...>
Anatoly Parshintsev <114...@us...>
Bernhard Rosenkränzer <be...@ba...>
bluew <bl...@us...>
Carsten Gosvig <403...@us...>
cgsfv <cg...@us...>
Craig Blackmore <cra...@em...>
Dan Robertson <dan...@gm...>
Darius Rad <da...@bl...>
dave-estes-syzexion <537...@us...>
Dmitry Ryzhov <dmi...@cl...>
Dolu1990 <cha...@gm...>
Emmanuel Blot <emm...@fr...>
Ernie Edgar <431...@us...>
Evgeniy Naydanov <evg...@sy...>
Farid Khaydari <f.k...@sy...>
Gleb Gagarin <gl...@si...>
Greg Savin <431...@us...>
Hang Xu <xu...@es...>
Hsiangkai <Hsi...@gm...>
Jan Matyas <jan...@co...>
jhjung81 <489...@us...>
Jiuyang Liu <li...@ji...>
Kaspar Schleiser <ka...@sc...>
Khem Raj <raj...@gm...>
Kirill Radkin <kir...@sy...>
liangzhen <zhe...@sp...>
Liviu Ionescu <il...@li...>
Marc Schink <ope...@ma...>
Megan Wachs <me...@si...>
Nils Wistoff <gi...@wi...>
Palmer Dabbelt <pa...@da...>
panciyan <pan...@es...>
Parshintsev Anatoly <ana...@sy...>
Paul George <com...@gm...>
Pavel S. Smirnov <Pau...@gm...>
Philipp Wagner <ma...@ph...>
Ryan Macdonald <rm...@si...>
Samuel Obuch <sam...@gm...>
Tarek BOCHKATI <tar...@gm...>
Tim Newsome <ti...@ca...>
Tobias Kaiser <ma...@tb...>
Tom Hebb <tom...@gm...>
Tommy Murphy <tom...@ho...>
wxjstz <wx...@12...>
wzgpeter <wzg...@ou...>
Xiang W <wx...@12...>
zhusonghe <zhu...@es...>
Checkpatch-ignore MULTISTATEMENT_MACRO_USE_DO_WHILE is added to allow a
macro in riscv-013.c that can't use do/while because it expands to a
"case ...:" statement.
Checkpatch-ignore TRAILING_SEMICOLON is added to allow a construct in
riscv-013.c where a macro expands to either code (where it needs the
semicolon) or a member of an enum (where it needs a comma).
Checkpatch-ignore LONG_LINE_COMMENT and NEW_TYPEDEFS lines are added for
the sake of the autogenerated files from riscv-debug-spec.
All non-autogenerated files have been updated for checkpatch compliance.
Checkpatch-ignore: LONG_LINE_COMMENT
Checkpatch-ignore: NEW_TYPEDEFS
Checkpatch-ignore: MULTISTATEMENT_MACRO_USE_DO_WHILE
Checkpatch-ignore: TRAILING_SEMICOLON
Change-Id: Ie594915a4d6e6f9d9dad6016b176ab76409a099a
Signed-off-by: Bernhard Rosenkränzer <be...@ba...>
Reviewed-on: https://review.openocd.org/c/openocd/+/8893
Tested-by: jenkins
Reviewed-by: Evgeniy Naydanov <evg...@sy...>
Reviewed-by: Tomas Vanek <va...@fb...>
diff --git a/src/target/riscv/Makefile.am b/src/target/riscv/Makefile.am
index 4b6a74f0b..189edb3e6 100644
--- a/src/target/riscv/Makefile.am
+++ b/src/target/riscv/Makefile.am
@@ -2,17 +2,31 @@
noinst_LTLIBRARIES += %D%/libriscv.la
%C%_libriscv_la_SOURCES = \
- %D%/asm.h \
%D%/batch.h \
%D%/debug_defines.h \
+ %D%/debug_reg_printer.h \
%D%/encoding.h \
+ %D%/field_helpers.h \
%D%/gdb_regs.h \
%D%/opcodes.h \
%D%/program.h \
%D%/riscv.h \
+ %D%/riscv_reg_impl.h \
+ %D%/riscv_reg.h \
+ %D%/riscv-011.h \
+ %D%/riscv-011_reg.h \
+ %D%/riscv-013.h \
+ %D%/riscv-013_reg.h \
%D%/batch.c \
%D%/program.c \
%D%/riscv-011.c \
+ %D%/riscv-011_reg.c \
%D%/riscv-013.c \
+ %D%/riscv-013_reg.c \
%D%/riscv.c \
- %D%/riscv_semihosting.c
+ %D%/riscv_reg.c \
+ %D%/riscv_semihosting.c \
+ %D%/debug_defines.c \
+ %D%/debug_reg_printer.c
+
+STARTUP_TCL_SRCS += %D%/startup.tcl
diff --git a/src/target/riscv/asm.h b/src/target/riscv/asm.h
deleted file mode 100644
index 6ceb8c9bd..000000000
--- a/src/target/riscv/asm.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#ifndef TARGET__RISCV__ASM_H
-#define TARGET__RISCV__ASM_H
-
-#include "riscv.h"
-
-/*** Version-independent functions that we don't want in the main address space. ***/
-
-static uint32_t load(const struct target *target, unsigned int rd,
- unsigned int base, uint16_t offset) __attribute__ ((unused));
-static uint32_t load(const struct target *target, unsigned int rd,
- unsigned int base, uint16_t offset)
-{
- switch (riscv_xlen(target)) {
- case 32:
- return lw(rd, base, offset);
- case 64:
- return ld(rd, base, offset);
- }
- assert(0);
- return 0; /* Silence -Werror=return-type */
-}
-
-static uint32_t store(const struct target *target, unsigned int src,
- unsigned int base, uint16_t offset) __attribute__ ((unused));
-static uint32_t store(const struct target *target, unsigned int src,
- unsigned int base, uint16_t offset)
-{
- switch (riscv_xlen(target)) {
- case 32:
- return sw(src, base, offset);
- case 64:
- return sd(src, base, offset);
- }
- assert(0);
- return 0; /* Silence -Werror=return-type */
-}
-
-#endif
diff --git a/src/target/riscv/batch.c b/src/target/riscv/batch.c
index e3f8ff3d4..ec68b3798 100644
--- a/src/target/riscv/batch.c
+++ b/src/target/riscv/batch.c
@@ -6,67 +6,90 @@
#include "batch.h"
#include "debug_defines.h"
+#include "debug_reg_printer.h"
#include "riscv.h"
+#include "field_helpers.h"
-#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1)))
-#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
-
+// TODO: DTM_DMI_MAX_ADDRESS_LENGTH should be reduced to 32 (per the debug spec)
#define DTM_DMI_MAX_ADDRESS_LENGTH ((1<<DTM_DTMCS_ABITS_LENGTH)-1)
#define DMI_SCAN_MAX_BIT_LENGTH (DTM_DMI_MAX_ADDRESS_LENGTH + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH)
+
#define DMI_SCAN_BUF_SIZE (DIV_ROUND_UP(DMI_SCAN_MAX_BIT_LENGTH, 8))
-static void dump_field(int idle, const struct scan_field *field);
+/* Reserve extra room in the batch (needed for the last NOP operation) */
+#define BATCH_RESERVED_SCANS 1
+
+static unsigned int get_dmi_scan_length(const struct target *target)
+{
+ const unsigned int abits = riscv_get_dmi_address_bits(target);
+ assert(abits > 0);
+ assert(abits <= DTM_DMI_MAX_ADDRESS_LENGTH);
+
+ return abits + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH;
+}
-struct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans, size_t idle)
+struct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans)
{
- scans += 4;
+ scans += BATCH_RESERVED_SCANS;
struct riscv_batch *out = calloc(1, sizeof(*out));
- if (!out)
- goto error0;
+ if (!out) {
+ LOG_ERROR("Failed to allocate struct riscv_batch");
+ return NULL;
+ }
+
out->target = target;
out->allocated_scans = scans;
- out->idle_count = idle;
- out->data_out = malloc(sizeof(*out->data_out) * (scans) * DMI_SCAN_BUF_SIZE);
+ out->last_scan = RISCV_SCAN_TYPE_INVALID;
+ out->was_run = false;
+ out->last_scan_delay = 0;
+
+ out->data_out = NULL;
+ out->data_in = NULL;
+ out->fields = NULL;
+ out->delay_classes = NULL;
+ out->bscan_ctxt = NULL;
+ out->read_keys = NULL;
+
+ /* FIXME: There is potential for memory usage reduction. We could allocate
+ * smaller buffers than DMI_SCAN_BUF_SIZE (that is, buffers that correspond to
+ * the real DR scan length on the given target) */
+ out->data_out = malloc(sizeof(*out->data_out) * scans * DMI_SCAN_BUF_SIZE);
if (!out->data_out) {
LOG_ERROR("Failed to allocate data_out in RISC-V batch.");
- goto error1;
+ goto alloc_error;
};
- out->data_in = malloc(sizeof(*out->data_in) * (scans) * DMI_SCAN_BUF_SIZE);
+ out->data_in = malloc(sizeof(*out->data_in) * scans * DMI_SCAN_BUF_SIZE);
if (!out->data_in) {
LOG_ERROR("Failed to allocate data_in in RISC-V batch.");
- goto error2;
+ goto alloc_error;
}
- out->fields = malloc(sizeof(*out->fields) * (scans));
+ out->fields = malloc(sizeof(*out->fields) * scans);
if (!out->fields) {
LOG_ERROR("Failed to allocate fields in RISC-V batch.");
- goto error3;
+ goto alloc_error;
+ }
+ out->delay_classes = malloc(sizeof(*out->delay_classes) * scans);
+ if (!out->delay_classes) {
+ LOG_ERROR("Failed to allocate delay_classes in RISC-V batch.");
+ goto alloc_error;
}
if (bscan_tunnel_ir_width != 0) {
- out->bscan_ctxt = malloc(sizeof(*out->bscan_ctxt) * (scans));
+ out->bscan_ctxt = malloc(sizeof(*out->bscan_ctxt) * scans);
if (!out->bscan_ctxt) {
LOG_ERROR("Failed to allocate bscan_ctxt in RISC-V batch.");
- goto error4;
+ goto alloc_error;
}
}
- out->last_scan = RISCV_SCAN_TYPE_INVALID;
- out->read_keys = malloc(sizeof(*out->read_keys) * (scans));
+ out->read_keys = malloc(sizeof(*out->read_keys) * scans);
if (!out->read_keys) {
LOG_ERROR("Failed to allocate read_keys in RISC-V batch.");
- goto error5;
+ goto alloc_error;
}
+
return out;
-error5:
- free(out->bscan_ctxt);
-error4:
- free(out->fields);
-error3:
- free(out->data_in);
-error2:
- free(out->data_out);
-error1:
- free(out);
-error0:
+alloc_error:
+ riscv_batch_free(out);
return NULL;
}
@@ -75,6 +98,7 @@ void riscv_batch_free(struct riscv_batch *batch)
free(batch->data_in);
free(batch->data_out);
free(batch->fields);
+ free(batch->delay_classes);
free(batch->bscan_ctxt);
free(batch->read_keys);
free(batch);
@@ -82,32 +106,209 @@ void riscv_batch_free(struct riscv_batch *batch)
bool riscv_batch_full(struct riscv_batch *batch)
{
- return batch->used_scans > (batch->allocated_scans - 4);
+ return riscv_batch_available_scans(batch) == 0;
+}
+
+static bool riscv_batch_was_scan_busy(const struct riscv_batch *batch,
+ size_t scan_idx)
+{
+ assert(batch->was_run);
+ assert(scan_idx < batch->used_scans);
+ const struct scan_field *field = batch->fields + scan_idx;
+ assert(field->in_value);
+ const uint64_t in = buf_get_u64(field->in_value, 0, field->num_bits);
+ return get_field(in, DTM_DMI_OP) == DTM_DMI_OP_BUSY;
}
-int riscv_batch_run(struct riscv_batch *batch)
+static void add_idle_before_batch(const struct riscv_batch *batch, size_t start_idx,
+ const struct riscv_scan_delays *delays)
{
- if (batch->used_scans == 0) {
- LOG_DEBUG("Ignoring empty batch.");
- return ERROR_OK;
+ if (!batch->was_run)
+ return;
+ /* Get the delay type of the scan that resulted in the busy response.
+ * Since DMI interactions always end with a NOP, if "start_idx" is zero
+ * the base delay value is used.
+ */
+ const enum riscv_scan_delay_class delay_class = start_idx > 0
+ ? batch->delay_classes[start_idx - 1]
+ : RISCV_DELAY_BASE;
+ const unsigned int new_delay = riscv_scan_get_delay(delays, delay_class);
+ if (new_delay <= batch->last_scan_delay)
+ return;
+ const unsigned int idle_change = new_delay - batch->last_scan_delay;
+ LOG_TARGET_DEBUG(batch->target, "Adding %u idle cycles before the batch.",
+ idle_change);
+ jtag_add_runtest(idle_change, TAP_IDLE);
+}
+
+static unsigned int get_delay(const struct riscv_batch *batch, size_t scan_idx,
+ const struct riscv_scan_delays *delays, bool resets_delays,
+ size_t reset_delays_after)
+{
+ assert(batch);
+ assert(scan_idx < batch->used_scans);
+ const bool delays_were_reset = resets_delays
+ && (scan_idx >= reset_delays_after);
+ const enum riscv_scan_delay_class delay_class =
+ batch->delay_classes[scan_idx];
+ const unsigned int delay = riscv_scan_get_delay(delays, delay_class);
+ return delays_were_reset ? 0 : delay;
+}
+
+static unsigned int decode_dmi(const struct riscv_batch *batch, char *text,
+ uint32_t address, uint32_t data)
+{
+ static const struct {
+ uint32_t address;
+ enum riscv_debug_reg_ordinal ordinal;
+ } description[] = {
+ {DM_DMCONTROL, DM_DMCONTROL_ORDINAL},
+ {DM_DMSTATUS, DM_DMSTATUS_ORDINAL},
+ {DM_ABSTRACTCS, DM_ABSTRACTCS_ORDINAL},
+ {DM_COMMAND, DM_COMMAND_ORDINAL},
+ {DM_SBCS, DM_SBCS_ORDINAL}
+ };
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(description); i++) {
+ if (riscv_get_dmi_address(batch->target, description[i].address)
+ == address) {
+ const riscv_debug_reg_ctx_t context = {
+ .XLEN = { .value = 0, .is_set = false },
+ .DXLEN = { .value = 0, .is_set = false },
+ .abits = { .value = 0, .is_set = false },
+ };
+ return riscv_debug_reg_to_s(text, description[i].ordinal,
+ context, data, RISCV_DEBUG_REG_HIDE_ALL_0);
+ }
+ }
+ if (text)
+ text[0] = '\0';
+ return 0;
+}
+
+static void log_dmi_decoded(const struct riscv_batch *batch, bool write,
+ uint32_t address, uint32_t data)
+{
+ const size_t size = decode_dmi(batch, /* text */ NULL, address, data) + 1;
+ char * const decoded = malloc(size);
+ if (!decoded) {
+ LOG_ERROR("Not enough memory to allocate %zu bytes.", size);
+ return;
+ }
+ decode_dmi(batch, decoded, address, data);
+ LOG_DEBUG("%s: %s", write ? "write" : "read", decoded);
+ free(decoded);
+}
+
+static void log_batch(const struct riscv_batch *batch, size_t start_idx,
+ const struct riscv_scan_delays *delays, bool resets_delays,
+ size_t reset_delays_after)
+{
+ if (debug_level < LOG_LVL_DEBUG)
+ return;
+
+ const unsigned int abits = riscv_get_dmi_address_bits(batch->target);
+
+ /* Determine the "op" and "address" of the scan that preceded the first
+ * executed scan.
+ * FIXME: The code here assumes that there were no DMI operations between
+ * the last execution of the batch and the current one.
+ * Caching the info about the last executed DMI scan in "dm013_info_t"
+ * would be a more robust solution.
+ */
+ bool last_scan_was_read = false;
+ uint32_t last_scan_address = (uint32_t)(-1) /* to silence maybe-uninitialized */;
+ if (start_idx > 0) {
+ const struct scan_field * const field = &batch->fields[start_idx - 1];
+ assert(field->out_value);
+ last_scan_was_read = buf_get_u32(field->out_value, DTM_DMI_OP_OFFSET,
+ DTM_DMI_OP_LENGTH) == DTM_DMI_OP_READ;
+ last_scan_address = buf_get_u32(field->out_value,
+ DTM_DMI_ADDRESS_OFFSET, abits);
}
- riscv_batch_add_nop(batch);
+ /* Decode and log every executed scan */
+ for (size_t i = start_idx; i < batch->used_scans; ++i) {
+ static const char * const op_string[] = {"-", "r", "w", "?"};
+ const unsigned int delay = get_delay(batch, i, delays, resets_delays,
+ reset_delays_after);
+ const struct scan_field * const field = &batch->fields[i];
- for (size_t i = 0; i < batch->used_scans; ++i) {
+ assert(field->out_value);
+ const unsigned int out_op = buf_get_u32(field->out_value,
+ DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH);
+ const uint32_t out_data = buf_get_u32(field->out_value,
+ DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH);
+ const uint32_t out_address = buf_get_u32(field->out_value,
+ DTM_DMI_ADDRESS_OFFSET, abits);
+ if (field->in_value) {
+ static const char * const status_string[] = {
+ "+", "?", "F", "b"
+ };
+ const unsigned int in_op = buf_get_u32(field->in_value,
+ DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH);
+ const uint32_t in_data = buf_get_u32(field->in_value,
+ DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH);
+ const uint32_t in_address = buf_get_u32(field->in_value,
+ DTM_DMI_ADDRESS_OFFSET, abits);
+
+ LOG_DEBUG("%db %s %08" PRIx32 " @%02" PRIx32
+ " -> %s %08" PRIx32 " @%02" PRIx32 "; %ui",
+ field->num_bits, op_string[out_op], out_data, out_address,
+ status_string[in_op], in_data, in_address, delay);
+
+ if (last_scan_was_read && in_op == DTM_DMI_OP_SUCCESS)
+ log_dmi_decoded(batch, /*write*/ false,
+ last_scan_address, in_data);
+ } else {
+ LOG_DEBUG("%db %s %08" PRIx32 " @%02" PRIx32 " -> ?; %ui",
+ field->num_bits, op_string[out_op], out_data, out_address,
+ delay);
+ }
+
+ if (out_op == DTM_DMI_OP_WRITE)
+ log_dmi_decoded(batch, /*write*/ true, out_address,
+ out_data);
+
+ last_scan_was_read = out_op == DTM_DMI_OP_READ;
+ last_scan_address = out_address;
+ }
+}
+
+int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
+ const struct riscv_scan_delays *delays, bool resets_delays,
+ size_t reset_delays_after)
+{
+ assert(batch->used_scans);
+ assert(start_idx < batch->used_scans);
+ assert(batch->last_scan == RISCV_SCAN_TYPE_NOP);
+ assert(!batch->was_run || riscv_batch_was_scan_busy(batch, start_idx));
+ assert(start_idx == 0 || !riscv_batch_was_scan_busy(batch, start_idx - 1));
+
+ if (batch->was_run)
+ add_idle_before_batch(batch, start_idx, delays);
+
+ LOG_TARGET_DEBUG(batch->target, "Running batch of scans [%zu, %zu)",
+ start_idx, batch->used_scans);
+
+ unsigned int delay = 0 /* to silence maybe-uninitialized */;
+ for (size_t i = start_idx; i < batch->used_scans; ++i) {
if (bscan_tunnel_ir_width != 0)
- riscv_add_bscan_tunneled_scan(batch->target, batch->fields+i, batch->bscan_ctxt+i);
+ riscv_add_bscan_tunneled_scan(batch->target->tap, batch->fields + i,
+ batch->bscan_ctxt + i);
else
jtag_add_dr_scan(batch->target->tap, 1, batch->fields + i, TAP_IDLE);
- if (batch->idle_count > 0)
- jtag_add_runtest(batch->idle_count, TAP_IDLE);
+ delay = get_delay(batch, i, delays, resets_delays,
+ reset_delays_after);
+ if (delay > 0)
+ jtag_add_runtest(delay, TAP_IDLE);
}
keep_alive();
if (jtag_execute_queue() != ERROR_OK) {
- LOG_ERROR("Unable to execute JTAG queue");
+ LOG_TARGET_ERROR(batch->target, "Unable to execute JTAG queue");
return ERROR_FAIL;
}
@@ -115,40 +316,69 @@ int riscv_batch_run(struct riscv_batch *batch)
if (bscan_tunnel_ir_width != 0) {
/* need to right-shift "in" by one bit, because of clock skew between BSCAN TAP and DM TAP */
- for (size_t i = 0; i < batch->used_scans; ++i) {
+ for (size_t i = start_idx; i < batch->used_scans; ++i) {
if ((batch->fields + i)->in_value)
buffer_shr((batch->fields + i)->in_value, DMI_SCAN_BUF_SIZE, 1);
}
}
- for (size_t i = 0; i < batch->used_scans; ++i)
- dump_field(batch->idle_count, batch->fields + i);
-
+ log_batch(batch, start_idx, delays, resets_delays, reset_delays_after);
+ batch->was_run = true;
+ batch->last_scan_delay = delay;
return ERROR_OK;
}
-void riscv_batch_add_dmi_write(struct riscv_batch *batch, unsigned int address, uint64_t data)
+void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint32_t address, uint32_t data,
+ bool read_back, enum riscv_scan_delay_class delay_class)
{
+ // TODO: Check that the bit width of "address" is no more than dtmcs.abits,
+ // otherwise return an error (during batch creation or when the batch is executed).
+
assert(batch->used_scans < batch->allocated_scans);
struct scan_field *field = batch->fields + batch->used_scans;
- field->num_bits = riscv_dmi_write_u64_bits(batch->target);
- field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
- field->in_value = (void *)(batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE);
- riscv_fill_dmi_write_u64(batch->target, (char *)field->out_value, address, data);
- riscv_fill_dmi_nop_u64(batch->target, (char *)field->in_value);
+
+ field->num_bits = get_dmi_scan_length(batch->target);
+ assert(field->num_bits <= DMI_SCAN_MAX_BIT_LENGTH);
+
+ uint8_t *out_value = batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE;
+ uint8_t *in_value = batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE;
+
+ field->out_value = out_value;
+ riscv_fill_dmi_write(batch->target, out_value, address, data);
+
+ if (read_back) {
+ field->in_value = in_value;
+ riscv_fill_dm_nop(batch->target, in_value);
+ } else {
+ field->in_value = NULL;
+ }
+
+ batch->delay_classes[batch->used_scans] = delay_class;
batch->last_scan = RISCV_SCAN_TYPE_WRITE;
batch->used_scans++;
}
-size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, unsigned int address)
+size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint32_t address,
+ enum riscv_scan_delay_class delay_class)
{
+ // TODO: Check that the bit width of "address" is no more than dtmcs.abits,
+ // otherwise return an error (during batch creation or when the batch is executed).
+
assert(batch->used_scans < batch->allocated_scans);
struct scan_field *field = batch->fields + batch->used_scans;
- field->num_bits = riscv_dmi_write_u64_bits(batch->target);
- field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
- field->in_value = (void *)(batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE);
- riscv_fill_dmi_read_u64(batch->target, (char *)field->out_value, address);
- riscv_fill_dmi_nop_u64(batch->target, (char *)field->in_value);
+
+ field->num_bits = get_dmi_scan_length(batch->target);
+ assert(field->num_bits <= DMI_SCAN_MAX_BIT_LENGTH);
+
+ uint8_t *out_value = batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE;
+ uint8_t *in_value = batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE;
+
+ field->out_value = out_value;
+ field->in_value = in_value;
+ riscv_fill_dmi_read(batch->target, out_value, address);
+ riscv_fill_dm_nop(batch->target, in_value);
+
+ batch->delay_classes[batch->used_scans] = delay_class;
batch->last_scan = RISCV_SCAN_TYPE_READ;
batch->used_scans++;
@@ -156,21 +386,21 @@ size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, unsigned int address)
return batch->read_keys_used++;
}
-uint32_t riscv_batch_get_dmi_read_op(struct riscv_batch *batch, size_t key)
+uint32_t riscv_batch_get_dmi_read_op(const struct riscv_batch *batch, size_t key)
{
assert(key < batch->read_keys_used);
size_t index = batch->read_keys[key];
- assert(index <= batch->used_scans);
+ assert(index < batch->used_scans);
uint8_t *base = batch->data_in + DMI_SCAN_BUF_SIZE * index;
/* extract "op" field from the DMI read result */
return buf_get_u32(base, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH);
}
-uint32_t riscv_batch_get_dmi_read_data(struct riscv_batch *batch, size_t key)
+uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t key)
{
assert(key < batch->read_keys_used);
size_t index = batch->read_keys[key];
- assert(index <= batch->used_scans);
+ assert(index < batch->used_scans);
uint8_t *base = batch->data_in + DMI_SCAN_BUF_SIZE * index;
/* extract "data" field from the DMI read result */
return buf_get_u32(base, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH);
@@ -180,48 +410,48 @@ void riscv_batch_add_nop(struct riscv_batch *batch)
{
assert(batch->used_scans < batch->allocated_scans);
struct scan_field *field = batch->fields + batch->used_scans;
- field->num_bits = riscv_dmi_write_u64_bits(batch->target);
- field->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);
- field->in_value = (void *)(batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE);
- riscv_fill_dmi_nop_u64(batch->target, (char *)field->out_value);
- riscv_fill_dmi_nop_u64(batch->target, (char *)field->in_value);
+
+ field->num_bits = get_dmi_scan_length(batch->target);
+ assert(field->num_bits <= DMI_SCAN_MAX_BIT_LENGTH);
+
+ uint8_t *out_value = batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE;
+ uint8_t *in_value = batch->data_in + batch->used_scans * DMI_SCAN_BUF_SIZE;
+
+ field->out_value = out_value;
+ field->in_value = in_value;
+ riscv_fill_dm_nop(batch->target, out_value);
+ riscv_fill_dm_nop(batch->target, in_value);
+
+ /* DMI NOP never triggers any debug module operation,
+ * so the shortest (base) delay can be used. */
+ batch->delay_classes[batch->used_scans] = RISCV_DELAY_BASE;
batch->last_scan = RISCV_SCAN_TYPE_NOP;
batch->used_scans++;
}
-void dump_field(int idle, const struct scan_field *field)
+size_t riscv_batch_available_scans(struct riscv_batch *batch)
{
- static const char * const op_string[] = {"-", "r", "w", "?"};
- static const char * const status_string[] = {"+", "?", "F", "b"};
-
- if (debug_level < LOG_LVL_DEBUG)
- return;
+ assert(batch->allocated_scans >= (batch->used_scans + BATCH_RESERVED_SCANS));
+ return batch->allocated_scans - batch->used_scans - BATCH_RESERVED_SCANS;
+}
- assert(field->out_value);
- uint64_t out = buf_get_u64(field->out_value, 0, field->num_bits);
- unsigned int out_op = get_field(out, DTM_DMI_OP);
- unsigned int out_data = get_field(out, DTM_DMI_DATA);
- unsigned int out_address = out >> DTM_DMI_ADDRESS_OFFSET;
-
- if (field->in_value) {
- uint64_t in = buf_get_u64(field->in_value, 0, field->num_bits);
- unsigned int in_op = get_field(in, DTM_DMI_OP);
- unsigned int in_data = get_field(in, DTM_DMI_DATA);
- unsigned int in_address = in >> DTM_DMI_ADDRESS_OFFSET;
-
- log_printf_lf(LOG_LVL_DEBUG,
- __FILE__, __LINE__, __PRETTY_FUNCTION__,
- "%ub %s %08x @%02x -> %s %08x @%02x; %di",
- field->num_bits, op_string[out_op], out_data, out_address,
- status_string[in_op], in_data, in_address, idle);
- } else {
- log_printf_lf(LOG_LVL_DEBUG,
- __FILE__, __LINE__, __PRETTY_FUNCTION__, "%ub %s %08x @%02x -> ?; %di",
- field->num_bits, op_string[out_op], out_data, out_address, idle);
- }
+bool riscv_batch_was_batch_busy(const struct riscv_batch *batch)
+{
+ assert(batch->was_run);
+ assert(batch->used_scans);
+ assert(batch->last_scan == RISCV_SCAN_TYPE_NOP);
+ return riscv_batch_was_scan_busy(batch, batch->used_scans - 1);
}
-size_t riscv_batch_available_scans(struct riscv_batch *batch)
+size_t riscv_batch_finished_scans(const struct riscv_batch *batch)
{
- return batch->allocated_scans - batch->used_scans - 4;
+ if (!riscv_batch_was_batch_busy(batch)) {
+ /* Whole batch succeeded. */
+ return batch->used_scans;
+ }
+ assert(batch->used_scans);
+ size_t first_busy = 0;
+ while (!riscv_batch_was_scan_busy(batch, first_busy))
+ ++first_busy;
+ return first_busy;
}
diff --git a/src/target/riscv/batch.h b/src/target/riscv/batch.h
index 537fa5923..5d8b57234 100644
--- a/src/target/riscv/batch.h
+++ b/src/target/riscv/batch.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef TARGET__RISCV__SCANS_H
-#define TARGET__RISCV__SCANS_H
+#ifndef OPENOCD_TARGET_RISCV_BATCH_H
+#define OPENOCD_TARGET_RISCV_BATCH_H
#include "target/target.h"
#include "jtag/jtag.h"
@@ -14,6 +14,112 @@ enum riscv_scan_type {
RISCV_SCAN_TYPE_WRITE,
};
+/* These types are used to specify how many JTAG RTI cycles to add after a
+ * scan.
+ */
+enum riscv_scan_delay_class {
+ /* Delay needed for accessing debug module registers: */
+ RISCV_DELAY_BASE,
+ /* Delay for execution of an abstract command: */
+ RISCV_DELAY_ABSTRACT_COMMAND,
+ /* Delay for System Bus read operation: */
+ RISCV_DELAY_SYSBUS_READ,
+ /* Delay for System Bus write operation: */
+ RISCV_DELAY_SYSBUS_WRITE
+};
+
+static inline const char *
+riscv_scan_delay_class_name(enum riscv_scan_delay_class delay_class)
+{
+ switch (delay_class) {
+ case RISCV_DELAY_BASE:
+ return "DM access";
+ case RISCV_DELAY_ABSTRACT_COMMAND:
+ return "Abstract Command";
+ case RISCV_DELAY_SYSBUS_READ:
+ return "System Bus read";
+ case RISCV_DELAY_SYSBUS_WRITE:
+ return "System Bus write";
+ }
+ assert(0);
+ return NULL;
+}
+
+/* The scan delay values are passed to "jtag_add_runtest()", which accepts an
+ * "int". Therefore, the passed value should be no greater than "INT_MAX".
+ *
+ * Since the resulting delay value can be a sum of two individual delays,
+ * individual delays are limited to "INT_MAX / 2" to prevent overflow of the
+ * final sum.
+ */
+#define RISCV_SCAN_DELAY_MAX (INT_MAX / 2)
+
+struct riscv_scan_delays {
+ unsigned int base_delay;
+ unsigned int ac_delay;
+ unsigned int sb_read_delay;
+ unsigned int sb_write_delay;
+};
+
+static inline unsigned int
+riscv_scan_get_delay(const struct riscv_scan_delays *delays,
+ enum riscv_scan_delay_class delay_class)
+{
+ switch (delay_class) {
+ case RISCV_DELAY_BASE:
+ return delays->base_delay;
+ case RISCV_DELAY_ABSTRACT_COMMAND:
+ return delays->base_delay + delays->ac_delay;
+ case RISCV_DELAY_SYSBUS_READ:
+ return delays->base_delay + delays->sb_read_delay;
+ case RISCV_DELAY_SYSBUS_WRITE:
+ return delays->base_delay + delays->sb_write_delay;
+ }
+ assert(0);
+ return 0;
+}
+
+static inline void riscv_scan_set_delay(struct riscv_scan_delays *delays,
+ enum riscv_scan_delay_class delay_class, unsigned int delay)
+{
+ assert(delay <= RISCV_SCAN_DELAY_MAX);
+ LOG_DEBUG("%s delay is set to %u.",
+ riscv_scan_delay_class_name(delay_class), delay);
+ switch (delay_class) {
+ case RISCV_DELAY_BASE:
+ delays->base_delay = delay;
+ return;
+ case RISCV_DELAY_ABSTRACT_COMMAND:
+ delays->ac_delay = delay;
+ return;
+ case RISCV_DELAY_SYSBUS_READ:
+ delays->sb_read_delay = delay;
+ return;
+ case RISCV_DELAY_SYSBUS_WRITE:
+ delays->sb_write_delay = delay;
+ return;
+ }
+ assert(0);
+}
+
+static inline int riscv_scan_increase_delay(struct riscv_scan_delays *delays,
+ enum riscv_scan_delay_class delay_class)
+{
+ const unsigned int delay = riscv_scan_get_delay(delays, delay_class);
+ const unsigned int delay_step = delay / 10 + 1;
+ if (delay > RISCV_SCAN_DELAY_MAX - delay_step) {
+ /* It's not clear if this issue actually occurs in real
+ * use-cases, so stick with a simple solution until the
+ * first bug report.
+ */
+ LOG_ERROR("Delay for %s (%d) is not increased anymore (maximum was reached).",
+ riscv_scan_delay_class_name(delay_class), delay);
+ return ERROR_FAIL;
+ }
+ riscv_scan_set_delay(delays, delay_class, delay + delay_step);
+ return ERROR_OK;
+}
+
/* A batch of multiple JTAG scans, which are grouped together to avoid the
* overhead of some JTAG adapters when sending single commands. This is
* designed to support block copies, as that's what we actually need to go
@@ -24,11 +130,10 @@ struct riscv_batch {
size_t allocated_scans;
size_t used_scans;
- size_t idle_count;
-
uint8_t *data_out;
uint8_t *data_in;
struct scan_field *fields;
+ enum riscv_scan_delay_class *delay_classes;
/* If in BSCAN mode, this field will be allocated (one per scan),
and utilized to tunnel all the scans in the batch. If not in
@@ -44,29 +149,75 @@ struct riscv_batch {
/* The read keys. */
size_t *read_keys;
size_t read_keys_used;
+
+ /* Flag indicating that the last run of the batch finished without an error
+ * from the underlying JTAG layer of OpenOCD - all scans were performed.
+ * However, RISC-V DMI "busy" condition could still have occurred.
+ */
+ bool was_run;
+ /* Number of RTI cycles used by the last scan on the last run.
+ * Only valid when `was_run` is set.
+ */
+ unsigned int last_scan_delay;
};
/* Allocates (or frees) a new scan set. "scans" is the maximum number of JTAG
- * scans that can be issued to this object, and idle is the number of JTAG idle
- * cycles between every real scan. */
-struct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans, size_t idle);
+ * scans that can be issued to this object. */
+struct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans);
void riscv_batch_free(struct riscv_batch *batch);
/* Checks to see if this batch is full. */
bool riscv_batch_full(struct riscv_batch *batch);
-/* Executes this scan batch. */
-int riscv_batch_run(struct riscv_batch *batch);
-
-/* Adds a DMI write to this batch. */
-void riscv_batch_add_dmi_write(struct riscv_batch *batch, unsigned int address, uint64_t data);
-
-/* DMI reads must be handled in two parts: the first one schedules a read and
+/* Executes this batch of JTAG DTM DMI scans, starting form "start" scan.
+ *
+ * If batch is run for the first time, it is expected that "start" is zero.
+ * It is expected that the batch ends with a DMI NOP operation.
+ *
+ * "idle_counts" specifies the number of JTAG Run-Test-Idle cycles to add
+ * after each scan depending on the delay class of the scan.
+ *
+ * If "resets_delays" is true, the algorithm will stop inserting idle cycles
+ * (JTAG Run-Test-Idle) after "reset_delays_after" number of scans is
+ * performed. This is useful for stress-testing of RISC-V algorithms in
+ * OpenOCD that are based on batches.
+ */
+int riscv_batch_run_from(struct riscv_batch *batch, size_t start_idx,
+ const struct riscv_scan_delays *delays, bool resets_delays,
+ size_t reset_delays_after);
+
+/* Get the number of scans successfully executed form this batch. */
+size_t riscv_batch_finished_scans(const struct riscv_batch *batch);
+
+/* Adds a DM register write to this batch. */
+void riscv_batch_add_dmi_write(struct riscv_batch *batch, uint32_t address, uint32_t data,
+ bool read_back, enum riscv_scan_delay_class delay_class);
+
+static inline void
+riscv_batch_add_dm_write(struct riscv_batch *batch, uint32_t address, uint32_t data,
+ bool read_back, enum riscv_scan_delay_class delay_type)
+{
+ return riscv_batch_add_dmi_write(batch,
+ riscv_get_dmi_address(batch->target, address), data,
+ read_back, delay_type);
+}
+
+/* DM register reads must be handled in two parts: the first one schedules a read and
* provides a key, the second one actually obtains the result of the read -
* status (op) and the actual data. */
-size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, unsigned int address);
-uint32_t riscv_batch_get_dmi_read_op(struct riscv_batch *batch, size_t key);
-uint32_t riscv_batch_get_dmi_read_data(struct riscv_batch *batch, size_t key);
+size_t riscv_batch_add_dmi_read(struct riscv_batch *batch, uint32_t address,
+ enum riscv_scan_delay_class delay_class);
+
+static inline size_t
+riscv_batch_add_dm_read(struct riscv_batch *batch, uint32_t address,
+ enum riscv_scan_delay_class delay_type)
+{
+ return riscv_batch_add_dmi_read(batch,
+ riscv_get_dmi_address(batch->target, address), delay_type);
+}
+
+uint32_t riscv_batch_get_dmi_read_op(const struct riscv_batch *batch, size_t key);
+uint32_t riscv_batch_get_dmi_read_data(const struct riscv_batch *batch, size_t key);
/* Scans in a NOP. */
void riscv_batch_add_nop(struct riscv_batch *batch);
@@ -74,4 +225,7 @@ void riscv_batch_add_nop(struct riscv_batch *batch);
/* Returns the number of available scans. */
size_t riscv_batch_available_scans(struct riscv_batch *batch);
-#endif
+/* Return true iff the last scan in the batch returned DMI_OP_BUSY. */
+bool riscv_batch_was_batch_busy(const struct riscv_batch *batch);
+
+#endif /* OPENOCD_TARGET_RISCV_BATCH_H */
diff --git a/src/target/riscv/debug_defines.c b/src/target/riscv/debug_defines.c
new file mode 100644
index 000000000..81644b2c2
--- /dev/null
+++ b/src/target/riscv/debug_defines.c
@@ -0,0 +1,3902 @@
+// SPDX-License-Identifier: BSD-2-Clause OR CC-BY-4.0
+/* This file was auto-generated by running 'make debug_defines' in https://github.com/riscv/riscv-debug-spec/ (22a7576) */
+
+#include "debug_defines.h"
+#include <stddef.h>
+#include <assert.h>
+static riscv_debug_reg_field_list_t dtm_idcode_get_version(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "Version",
+ .lsb = 0x1c,
+ .msb = 0x1f,
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_idcode_get_partnumber(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "PartNumber",
+ .lsb = 0xc,
+ .msb = 0x1b,
+ .values = NULL
+ },
+ .get_next = dtm_idcode_get_version
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_idcode_get_manufid(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "ManufId",
+ .lsb = 1,
+ .msb = 0xb,
+ .values = NULL
+ },
+ .get_next = dtm_idcode_get_partnumber
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_idcode_get_1(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "1",
+ .lsb = 0,
+ .msb = 0,
+ .values = NULL
+ },
+ .get_next = dtm_idcode_get_manufid
+ };
+ return result;
+}
+
+static const char *dtm_dtmcs_errinfo_values[8] = {
+ [0] = "not_implemented",
+ [1] = "dmi_error",
+ [2] = "communication_error",
+ [3] = "device_error",
+ [4] = "unknown"
+};
+static const char *dtm_dtmcs_version_values[16] = {
+ [0] = "0_11",
+ [1] = "1_0",
+ [15] = "custom"
+};
+static riscv_debug_reg_field_list_t dtm_dtmcs_get_abits(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "abits",
+ .lsb = 4,
+ .msb = 9,
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_dtmcs_get_errinfo(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "errinfo",
+ .lsb = 0x12,
+ .msb = 0x14,
+ .values = dtm_dtmcs_errinfo_values
+ },
+ .get_next = dtm_dtmcs_get_abits
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_dtmcs_get_dtmhardreset(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "dtmhardreset",
+ .lsb = 0x11,
+ .msb = 0x11,
+ .values = NULL
+ },
+ .get_next = dtm_dtmcs_get_errinfo
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_dtmcs_get_dmireset(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "dmireset",
+ .lsb = 0x10,
+ .msb = 0x10,
+ .values = NULL
+ },
+ .get_next = dtm_dtmcs_get_dtmhardreset
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_dtmcs_get_idle(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "idle",
+ .lsb = 0xc,
+ .msb = 0xe,
+ .values = NULL
+ },
+ .get_next = dtm_dtmcs_get_dmireset
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_dtmcs_get_dmistat(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "dmistat",
+ .lsb = 0xa,
+ .msb = 0xb,
+ .values = NULL
+ },
+ .get_next = dtm_dtmcs_get_idle
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_dtmcs_get_version(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "version",
+ .lsb = 0,
+ .msb = 3,
+ .values = dtm_dtmcs_version_values
+ },
+ .get_next = dtm_dtmcs_get_dmistat
+ };
+ return result;
+}
+
+static const char *dtm_dmi_op_values[4] = {};
+static riscv_debug_reg_field_list_t dtm_dmi_get_address(riscv_debug_reg_ctx_t context)
+{
+ assert(context.abits.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "address",
+ .lsb = 0x22,
+ .msb = (context.abits.value + 0x21),
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_dmi_get_data(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "data",
+ .lsb = 2,
+ .msb = 0x21,
+ .values = NULL
+ },
+ .get_next = dtm_dmi_get_address
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t dtm_dmi_get_op(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "op",
+ .lsb = 0,
+ .msb = 1,
+ .values = dtm_dmi_op_values
+ },
+ .get_next = dtm_dmi_get_data
+ };
+ return result;
+}
+
+
+static const char *csr_dcsr_debugver_values[16] = {
+ [0] = "none",
+ [4] = "1_0",
+ [15] = "custom"
+};
+static const char *csr_dcsr_extcause_values[8] = {
+ [0] = "critical_error"
+};
+static const char *csr_dcsr_cetrig_values[2] = {
+ [0] = "disabled",
+ [1] = "enabled"
+};
+static const char *csr_dcsr_pelp_values[2] = {
+ [0] = "NO_LP_EXPECTED",
+ [1] = "LP_EXPECTED"
+};
+static const char *csr_dcsr_ebreakvs_values[2] = {
+ [0] = "exception",
+ [1] = "debug_mode"
+};
+static const char *csr_dcsr_ebreakvu_values[2] = {
+ [0] = "exception",
+ [1] = "debug_mode"
+};
+static const char *csr_dcsr_ebreakm_values[2] = {
+ [0] = "exception",
+ [1] = "debug_mode"
+};
+static const char *csr_dcsr_ebreaks_values[2] = {
+ [0] = "exception",
+ [1] = "debug_mode"
+};
+static const char *csr_dcsr_ebreaku_values[2] = {
+ [0] = "exception",
+ [1] = "debug_mode"
+};
+static const char *csr_dcsr_stepie_values[2] = {
+ [0] = "interrupts_disabled",
+ [1] = "interrupts_enabled"
+};
+static const char *csr_dcsr_stopcount_values[2] = {
+ [0] = "normal",
+ [1] = "freeze"
+};
+static const char *csr_dcsr_stoptime_values[2] = {
+ [0] = "normal",
+ [1] = "freeze"
+};
+static const char *csr_dcsr_cause_values[8] = {
+ [1] = "ebreak",
+ [2] = "trigger",
+ [3] = "haltreq",
+ [4] = "step",
+ [5] = "resethaltreq",
+ [6] = "group",
+ [7] = "other"
+};
+static const char *csr_dcsr_mprven_values[2] = {
+ [0] = "disabled",
+ [1] = "enabled"
+};
+static riscv_debug_reg_field_list_t csr_dcsr_get_stoptime(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "stoptime",
+ .lsb = 9,
+ .msb = 9,
+ .values = csr_dcsr_stoptime_values
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_cause(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "cause",
+ .lsb = 6,
+ .msb = 8,
+ .values = csr_dcsr_cause_values
+ },
+ .get_next = csr_dcsr_get_stoptime
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_v(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "v",
+ .lsb = 5,
+ .msb = 5,
+ .values = NULL
+ },
+ .get_next = csr_dcsr_get_cause
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_mprven(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "mprven",
+ .lsb = 4,
+ .msb = 4,
+ .values = csr_dcsr_mprven_values
+ },
+ .get_next = csr_dcsr_get_v
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_nmip(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "nmip",
+ .lsb = 3,
+ .msb = 3,
+ .values = NULL
+ },
+ .get_next = csr_dcsr_get_mprven
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_debugver(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "debugver",
+ .lsb = 0x1c,
+ .msb = 0x1f,
+ .values = csr_dcsr_debugver_values
+ },
+ .get_next = csr_dcsr_get_nmip
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_extcause(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "extcause",
+ .lsb = 0x18,
+ .msb = 0x1a,
+ .values = csr_dcsr_extcause_values
+ },
+ .get_next = csr_dcsr_get_debugver
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_step(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "step",
+ .lsb = 2,
+ .msb = 2,
+ .values = NULL
+ },
+ .get_next = csr_dcsr_get_extcause
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_cetrig(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "cetrig",
+ .lsb = 0x13,
+ .msb = 0x13,
+ .values = csr_dcsr_cetrig_values
+ },
+ .get_next = csr_dcsr_get_step
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_pelp(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "pelp",
+ .lsb = 0x12,
+ .msb = 0x12,
+ .values = csr_dcsr_pelp_values
+ },
+ .get_next = csr_dcsr_get_cetrig
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_ebreakvs(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "ebreakvs",
+ .lsb = 0x11,
+ .msb = 0x11,
+ .values = csr_dcsr_ebreakvs_values
+ },
+ .get_next = csr_dcsr_get_pelp
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_ebreakvu(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "ebreakvu",
+ .lsb = 0x10,
+ .msb = 0x10,
+ .values = csr_dcsr_ebreakvu_values
+ },
+ .get_next = csr_dcsr_get_ebreakvs
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_ebreakm(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "ebreakm",
+ .lsb = 0xf,
+ .msb = 0xf,
+ .values = csr_dcsr_ebreakm_values
+ },
+ .get_next = csr_dcsr_get_ebreakvu
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_ebreaks(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "ebreaks",
+ .lsb = 0xd,
+ .msb = 0xd,
+ .values = csr_dcsr_ebreaks_values
+ },
+ .get_next = csr_dcsr_get_ebreakm
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_ebreaku(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "ebreaku",
+ .lsb = 0xc,
+ .msb = 0xc,
+ .values = csr_dcsr_ebreaku_values
+ },
+ .get_next = csr_dcsr_get_ebreaks
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_stepie(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "stepie",
+ .lsb = 0xb,
+ .msb = 0xb,
+ .values = csr_dcsr_stepie_values
+ },
+ .get_next = csr_dcsr_get_ebreaku
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_stopcount(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "stopcount",
+ .lsb = 0xa,
+ .msb = 0xa,
+ .values = csr_dcsr_stopcount_values
+ },
+ .get_next = csr_dcsr_get_stepie
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dcsr_get_prv(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "prv",
+ .lsb = 0,
+ .msb = 1,
+ .values = NULL
+ },
+ .get_next = csr_dcsr_get_stopcount
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dpc_get_dpc(riscv_debug_reg_ctx_t context)
+{
+ assert(context.DXLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "dpc",
+ .lsb = 0,
+ .msb = (context.DXLEN.value + -1),
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dscratch0_get_dscratch0(riscv_debug_reg_ctx_t context)
+{
+ assert(context.DXLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "dscratch0",
+ .lsb = 0,
+ .msb = (context.DXLEN.value + -1),
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_dscratch1_get_dscratch1(riscv_debug_reg_ctx_t context)
+{
+ assert(context.DXLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "dscratch1",
+ .lsb = 0,
+ .msb = (context.DXLEN.value + -1),
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_tselect_get_index(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "index",
+ .lsb = 0,
+ .msb = (context.XLEN.value + -1),
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static const char *csr_tdata1_type_values[16] = {
+ [0] = "none",
+ [1] = "legacy",
+ [2] = "mcontrol",
+ [3] = "icount",
+ [4] = "itrigger",
+ [5] = "etrigger",
+ [6] = "mcontrol6",
+ [7] = "tmexttrigger",
+ [15] = "disabled"
+};
+static const char *csr_tdata1_dmode_values[2] = {
+ [0] = "both",
+ [1] = "dmode"
+};
+static riscv_debug_reg_field_list_t csr_tdata1_get_dmode(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "dmode",
+ .lsb = (context.XLEN.value + -5),
+ .msb = (context.XLEN.value + -5),
+ .values = csr_tdata1_dmode_values
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_tdata1_get_type(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "type",
+ .lsb = (context.XLEN.value + -4),
+ .msb = (context.XLEN.value + -1),
+ .values = csr_tdata1_type_values
+ },
+ .get_next = csr_tdata1_get_dmode
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_tdata1_get_data(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "data",
+ .lsb = 0,
+ .msb = (context.XLEN.value + -6),
+ .values = NULL
+ },
+ .get_next = csr_tdata1_get_type
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_tdata2_get_data(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "data",
+ .lsb = 0,
+ .msb = (context.XLEN.value + -1),
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_tdata3_get_data(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "data",
+ .lsb = 0,
+ .msb = (context.XLEN.value + -1),
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static const char *csr_tinfo_version_values[256] = {
+ [0] = "0",
+ [1] = "1"
+};
+static riscv_debug_reg_field_list_t csr_tinfo_get_version(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "version",
+ .lsb = 0x18,
+ .msb = 0x1f,
+ .values = csr_tinfo_version_values
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_tinfo_get_info(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "info",
+ .lsb = 0,
+ .msb = 0xf,
+ .values = NULL
+ },
+ .get_next = csr_tinfo_get_version
+ };
+ return result;
+}
+
+static const char *csr_tcontrol_mte_values[2] = {
+ [0] = "disabled",
+ [1] = "enabled"
+};
+static riscv_debug_reg_field_list_t csr_tcontrol_get_mpte(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "mpte",
+ .lsb = 7,
+ .msb = 7,
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_tcontrol_get_mte(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "mte",
+ .lsb = 3,
+ .msb = 3,
+ .values = csr_tcontrol_mte_values
+ },
+ .get_next = csr_tcontrol_get_mpte
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_scontext_get_data(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "data",
+ .lsb = 0,
+ .msb = 0x1f,
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontext_get_hcontext(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "hcontext",
+ .lsb = 0,
+ .msb = 0xd,
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static const char *csr_mcontrol_select_values[2] = {
+ [0] = "address",
+ [1] = "data"
+};
+static const char *csr_mcontrol_timing_values[2] = {
+ [0] = "before",
+ [1] = "after"
+};
+static const char *csr_mcontrol_sizelo_values[4] = {};
+static const char *csr_mcontrol_action_values[16] = {
+ [0] = "breakpoint",
+ [1] = "debug_mode",
+ [2] = "trace_on",
+ [3] = "trace_off",
+ [4] = "trace_notify",
+ [8] = "external0",
+ [9] = "external1"
+};
+static const char *csr_mcontrol_chain_values[2] = {
+ [0] = "disabled",
+ [1] = "enabled"
+};
+static const char *csr_mcontrol_match_values[16] = {
+ [0] = "equal",
+ [1] = "napot",
+ [2] = "ge",
+ [3] = "lt",
+ [4] = "mask_low",
+ [5] = "mask_high",
+ [8] = "not_equal",
+ [9] = "not_napot",
+ [12] = "not_mask_low",
+ [13] = "not_mask_high"
+};
+static riscv_debug_reg_field_list_t csr_mcontrol_get_dmode(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "dmode",
+ .lsb = (context.XLEN.value + -5),
+ .msb = (context.XLEN.value + -5),
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_type(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "type",
+ .lsb = (context.XLEN.value + -4),
+ .msb = (context.XLEN.value + -1),
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_dmode
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_maskmax(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "maskmax",
+ .lsb = (context.XLEN.value + -0xb),
+ .msb = (context.XLEN.value + -6),
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_type
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_match(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "match",
+ .lsb = 7,
+ .msb = 0xa,
+ .values = csr_mcontrol_match_values
+ },
+ .get_next = csr_mcontrol_get_maskmax
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_m(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "m",
+ .lsb = 6,
+ .msb = 6,
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_match
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_s(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "s",
+ .lsb = 4,
+ .msb = 4,
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_m
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_u(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "u",
+ .lsb = 3,
+ .msb = 3,
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_s
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_sizehi(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "sizehi",
+ .lsb = 0x15,
+ .msb = 0x16,
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_u
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_hit(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "hit",
+ .lsb = 0x14,
+ .msb = 0x14,
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_sizehi
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_execute(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "execute",
+ .lsb = 2,
+ .msb = 2,
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_hit
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_select(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "select",
+ .lsb = 0x13,
+ .msb = 0x13,
+ .values = csr_mcontrol_select_values
+ },
+ .get_next = csr_mcontrol_get_execute
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_timing(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "timing",
+ .lsb = 0x12,
+ .msb = 0x12,
+ .values = csr_mcontrol_timing_values
+ },
+ .get_next = csr_mcontrol_get_select
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_sizelo(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "sizelo",
+ .lsb = 0x10,
+ .msb = 0x11,
+ .values = csr_mcontrol_sizelo_values
+ },
+ .get_next = csr_mcontrol_get_timing
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_action(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "action",
+ .lsb = 0xc,
+ .msb = 0xf,
+ .values = csr_mcontrol_action_values
+ },
+ .get_next = csr_mcontrol_get_sizelo
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_chain(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "chain",
+ .lsb = 0xb,
+ .msb = 0xb,
+ .values = csr_mcontrol_chain_values
+ },
+ .get_next = csr_mcontrol_get_action
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_store(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "store",
+ .lsb = 1,
+ .msb = 1,
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_chain
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol_get_load(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "load",
+ .lsb = 0,
+ .msb = 0,
+ .values = NULL
+ },
+ .get_next = csr_mcontrol_get_store
+ };
+ return result;
+}
+
+static const char *csr_mcontrol6_uncertain_values[2] = {
+ [0] = "certain",
+ [1] = "uncertain"
+};
+static const char *csr_mcontrol6_hit0_values[2] = {};
+static const char *csr_mcontrol6_select_values[2] = {
+ [0] = "address",
+ [1] = "data"
+};
+static const char *csr_mcontrol6_size_values[8] = {
+ [0] = "any",
+ [1] = "8bit",
+ [2] = "16bit",
+ [3] = "32bit",
+ [4] = "48bit",
+ [5] = "64bit",
+ [6] = "128bit"
+};
+static const char *csr_mcontrol6_action_values[16] = {
+ [0] = "breakpoint",
+ [1] = "debug_mode",
+ [2] = "trace_on",
+ [3] = "trace_off",
+ [4] = "trace_notify",
+ [8] = "external0",
+ [9] = "external1"
+};
+static const char *csr_mcontrol6_chain_values[2] = {
+ [0] = "disabled",
+ [1] = "enabled"
+};
+static const char *csr_mcontrol6_match_values[16] = {
+ [0] = "equal",
+ [1] = "napot",
+ [2] = "ge",
+ [3] = "lt",
+ [4] = "mask_low",
+ [5] = "mask_high",
+ [8] = "not_equal",
+ [9] = "not_napot",
+ [12] = "not_mask_low",
+ [13] = "not_mask_high"
+};
+static const char *csr_mcontrol6_uncertainen_values[2] = {
+ [0] = "disabled",
+ [1] = "enabled"
+};
+static riscv_debug_reg_field_list_t csr_mcontrol6_get_dmode(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "dmode",
+ .lsb = (context.XLEN.value + -5),
+ .msb = (context.XLEN.value + -5),
+ .values = NULL
+ },
+ .get_next = NULL
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol6_get_type(riscv_debug_reg_ctx_t context)
+{
+ assert(context.XLEN.is_set);
+ riscv_debug_reg_field_list_t result = {
+ .field = {
+ .name = "type",
+ .lsb = (context.XLEN.value + -4),
+ .msb = (context.XLEN.value + -1),
+ .values = NULL
+ },
+ .get_next = csr_mcontrol6_get_dmode
+ };
+ return result;
+}
+
+static riscv_debug_reg_field_list_t csr_mcontrol6_get_match(riscv_debug_reg_ctx_t context)
+{
+ riscv_debug_reg_field_list_t result = {
+ .field = {...
[truncated message content] |
|
From: openocd-gerrit <ope...@us...> - 2025-11-08 16:00:54
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via ab22b0bf8f23924d8c76d3affd9e11528ba18438 (commit)
from 2bb3e52436247e445e9cf0d7e18a6962688dff40 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit ab22b0bf8f23924d8c76d3affd9e11528ba18438
Author: Antonio Borneo <bor...@gm...>
Date: Mon Nov 3 11:18:02 2025 +0100
target: cortex-m: don't query cache on hla targets
The cache handling code is written and optimized for dap queuing.
On hla targets it causes a segmentation fault due to uninitialized
AP pointer still set to NULL.
While it's possible to modify the code to cope with hla targets,
this would lower the OpenOCD performance on modern adapters.
Make cache handling not available on hla targets.
Reported-by: Tomas Vanek <va...@fb...>
Change-Id: Ief4499caedcee477b9517a7ad4597d06b5cb061e
Signed-off-by: Antonio Borneo <bor...@gm...>
Fixes: 04da6e2c6246 ("target: cortex-m: add support for armv8m caches")
Reviewed-on: https://review.openocd.org/c/openocd/+/9202
Reviewed-by: Tomas Vanek <va...@fb...>
Tested-by: jenkins
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 21b611b29..9f0b6284b 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -3007,10 +3007,12 @@ int cortex_m_examine(struct target *target)
cortex_m->fp_num_code,
cortex_m->dwt_num_comp);
- retval = armv7m_identify_cache(target);
- if (retval != ERROR_OK) {
- LOG_ERROR("Cannot detect cache");
- return retval;
+ if (!armv7m->is_hla_target) {
+ retval = armv7m_identify_cache(target);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Cannot detect cache");
+ return retval;
+ }
}
}
-----------------------------------------------------------------------
Summary of changes:
src/target/cortex_m.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-08 16:00:37
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 2bb3e52436247e445e9cf0d7e18a6962688dff40 (commit)
from 04c6a6ee0eff09e22454b0990f47a41ebad7e345 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 2bb3e52436247e445e9cf0d7e18a6962688dff40
Author: Antonio Borneo <bor...@gm...>
Date: Fri Oct 24 16:38:18 2025 +0200
doc: update copyright year
We should update it every year, let's do it at least once per
release.
Change-Id: Ia2ba38cbd732bc923e0199b148b6878585b34a49
Signed-off-by: Antonio Borneo <bor...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9199
Tested-by: jenkins
diff --git a/doc/openocd.texi b/doc/openocd.texi
index aa4b391aa..e69a8f6b0 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -19,7 +19,7 @@ dated @value{UPDATED},
of the Open On-Chip Debugger (OpenOCD).
@itemize @bullet
-@item Copyright @copyright{} 2008-2022 The OpenOCD Project
+@item Copyright @copyright{} 2008-2025 The OpenOCD Project
@item Copyright @copyright{} 2007-2008 Spencer Oliver @email{spen@@spen-soft.co.uk}
@item Copyright @copyright{} 2008-2010 Oyvind Harboe @email{oyvind.harboe@@zylin.com}
@item Copyright @copyright{} 2008 Duane Ellis @email{openocd@@duaneellis.com}
-----------------------------------------------------------------------
Summary of changes:
doc/openocd.texi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-08 15:59:46
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 04c6a6ee0eff09e22454b0990f47a41ebad7e345 (commit)
from 52ea420dd2d662d00c25621ccb9d3af647d28d4f (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 04c6a6ee0eff09e22454b0990f47a41ebad7e345
Author: Erhan Kurubas <erh...@es...>
Date: Sat Nov 1 14:36:27 2025 +0100
tcl: add Espressif RISC-V config files
Add configuration files for Espressif RISC-V based chips:
- ESP32-C2, ESP32-C3, ESP32-C6, ESP32-H2 target configs
- Board configs for builtin USB-JTAG and FTDI interfaces
while adding the new config files:
- Fix indentation in existing Espressif config files
- Adapt esp_common.cfg with RISC-V support
- Add explicit 'transport select jtag' to interface configs to avoid
'DEPRECATED: auto-selecting transport' warning
Change-Id: I45fcbca2fe50888750e2e98a0a6773de86aad6d0
Signed-off-by: Erhan Kurubas <erh...@es...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9195
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 2202a8d98..aa4b391aa 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -630,7 +630,7 @@ emulation model of target hardware.
This is deprecated from Linux v5.3; prefer using @b{linuxgpiod}.
@item @b{esp_usb_jtag}
-@* A JTAG driver to communicate with builtin debug modules of Espressif ESP32-C3 and ESP32-S3 chips using OpenOCD.
+@* A JTAG driver to communicate with builtin debug modules of Espressif ESP32-C3, ESP32-C6, ESP32-H2 and ESP32-S3 chips using OpenOCD.
@item @b{ch347}
@* A JTAG driver that works with the WCH CH347F and CH347T chips.
@@ -3768,7 +3768,7 @@ buspirate led 1
@end deffn
@deffn {Interface Driver} {esp_usb_jtag}
-Espressif JTAG driver to communicate with ESP32-C3, ESP32-S3 chips and ESP USB Bridge board using OpenOCD.
+Espressif JTAG driver to communicate with ESP32-C3, ESP32-C6, ESP32-H2 and ESP32-S3 chips and ESP USB Bridge board using OpenOCD.
These chips have built-in JTAG circuitry and can be debugged without any additional hardware.
Only an USB cable connected to the D+/D- pins is necessary.
@@ -5146,6 +5146,10 @@ The current implementation supports eSi-32xx cores.
@item @code{esp32} -- this is an Espressif SoC with dual Xtensa cores.
@item @code{esp32s2} -- this is an Espressif SoC with single Xtensa core.
@item @code{esp32s3} -- this is an Espressif SoC with dual Xtensa cores.
+@item @code{esp32c2} -- this is an Espressif SoC with single RISC-V core.
+@item @code{esp32c3} -- this is an Espressif SoC with single RISC-V core.
+@item @code{esp32c6} -- this is an Espressif SoC with single RISC-V core.
+@item @code{esp32h2} -- this is an Espressif SoC with single RISC-V core.
@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.
diff --git a/tcl/board/esp32c2-ftdi.cfg b/tcl/board/esp32c2-ftdi.cfg
new file mode 100644
index 000000000..bc2b82f5a
--- /dev/null
+++ b/tcl/board/esp32c2-ftdi.cfg
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-C2 connected via ESP-Prog.
+#
+# For example, OpenOCD can be started for ESP32-C2 debugging on
+#
+# openocd -f board/esp32c2-ftdi.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/ftdi/esp32_devkitj_v1.cfg]
+# Source the ESP32-C2 configuration file
+source [find target/esp32c2.cfg]
+
+# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they
+# do not relate to OpenOCD trying to read from a memory range without physical
+# memory being present there), you can try lowering this.
+#
+# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz
+# if CPU frequency is 160MHz or 240MHz.
+adapter speed 20000
diff --git a/tcl/board/esp32c3-builtin.cfg b/tcl/board/esp32c3-builtin.cfg
new file mode 100644
index 000000000..9e19b1b93
--- /dev/null
+++ b/tcl/board/esp32c3-builtin.cfg
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-C3 connected via builtin USB-JTAG adapter.
+#
+# For example, OpenOCD can be started for ESP32-C3 debugging on
+#
+# openocd -f board/esp32c3-builtin.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/esp_usb_jtag.cfg]
+# Source the ESP32-C3 configuration file
+source [find target/esp32c3.cfg]
+
+adapter speed 40000
diff --git a/tcl/board/esp32c3-ftdi.cfg b/tcl/board/esp32c3-ftdi.cfg
new file mode 100644
index 000000000..55953742c
--- /dev/null
+++ b/tcl/board/esp32c3-ftdi.cfg
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-C3 connected via ESP-Prog.
+#
+# For example, OpenOCD can be started for ESP32-C3 debugging on
+#
+# openocd -f board/esp32c3-ftdi.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/ftdi/esp32_devkitj_v1.cfg]
+# Source the ESP32-C3 configuration file
+source [find target/esp32c3.cfg]
+
+# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they
+# do not relate to OpenOCD trying to read from a memory range without physical
+# memory being present there), you can try lowering this.
+#
+# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz
+# if CPU frequency is 160MHz or 240MHz.
+adapter speed 20000
diff --git a/tcl/board/esp32c6-builtin.cfg b/tcl/board/esp32c6-builtin.cfg
new file mode 100644
index 000000000..abc96b2d1
--- /dev/null
+++ b/tcl/board/esp32c6-builtin.cfg
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-C6 connected via builtin USB-JTAG adapter.
+#
+# For example, OpenOCD can be started for ESP32-C6 debugging on
+#
+# openocd -f board/esp32c6-builtin.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/esp_usb_jtag.cfg]
+# Source the ESP32-C6 configuration file
+source [find target/esp32c6.cfg]
+
+adapter speed 40000
diff --git a/tcl/board/esp32h2-builtin.cfg b/tcl/board/esp32h2-builtin.cfg
new file mode 100644
index 000000000..4455f9999
--- /dev/null
+++ b/tcl/board/esp32h2-builtin.cfg
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Example OpenOCD configuration file for ESP32-H2 connected via builtin USB-JTAG adapter.
+#
+# For example, OpenOCD can be started for ESP32-H2 debugging on
+#
+# openocd -f board/esp32h2-builtin.cfg
+#
+
+# Source the JTAG interface configuration file
+source [find interface/esp_usb_jtag.cfg]
+# Source the ESP32-H2 configuration file
+source [find target/esp32h2.cfg]
+
+adapter speed 40000
diff --git a/tcl/interface/esp_usb_jtag.cfg b/tcl/interface/esp_usb_jtag.cfg
index 40427d0e3..583a92d6a 100644
--- a/tcl/interface/esp_usb_jtag.cfg
+++ b/tcl/interface/esp_usb_jtag.cfg
@@ -7,3 +7,5 @@ adapter driver esp_usb_jtag
espusbjtag vid_pid 0x303a 0x1001
espusbjtag caps_descriptor 0x2000
+
+transport select jtag
diff --git a/tcl/interface/ftdi/esp32_devkitj_v1.cfg b/tcl/interface/ftdi/esp32_devkitj_v1.cfg
index 1b455a9ac..438d14be2 100644
--- a/tcl/interface/ftdi/esp32_devkitj_v1.cfg
+++ b/tcl/interface/ftdi/esp32_devkitj_v1.cfg
@@ -23,3 +23,5 @@ ftdi layout_signal LED4 -data 0x8000
# The target code doesn't handle SRST reset properly yet, so this is commented out:
# ftdi layout_signal nSRST -oe 0x0020
# reset_config srst_only
+
+transport select jtag
diff --git a/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg b/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg
index 1880bcbc5..c531f3da0 100644
--- a/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg
+++ b/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg
@@ -27,3 +27,5 @@ ftdi layout_signal LED2 -ndata 0x1000
# commented out:
# ftdi layout_signal nSRST -oe 0x0020
#Â reset_config srst_only
+
+transport select jtag
diff --git a/tcl/target/esp32.cfg b/tcl/target/esp32.cfg
index b30a17024..080329612 100644
--- a/tcl/target/esp32.cfg
+++ b/tcl/target/esp32.cfg
@@ -5,14 +5,14 @@
source [find target/esp_common.cfg]
# Target specific global variables
-set _CHIPNAME "esp32"
-set _CPUTAPID 0x120034e5
-set _ESP_ARCH "xtensa"
-set _ONLYCPU 3
-set _FLASH_VOLTAGE 3.3
-set _ESP_SMP_TARGET 1
-set _ESP_SMP_BREAK 1
-set _ESP_EFUSE_MAC_ADDR_REG 0x3ff5A004
+set _CHIPNAME "esp32"
+set _CPUTAPID 0x120034e5
+set _ESP_ARCH "xtensa"
+set _ONLYCPU 3
+set _FLASH_VOLTAGE 3.3
+set _ESP_SMP_TARGET 1
+set _ESP_SMP_BREAK 1
+set _ESP_EFUSE_MAC_ADDR_REG 0x3ff5A004
if { [info exists ESP32_ONLYCPU] } {
set _ONLYCPU $ESP32_ONLYCPU
diff --git a/tcl/target/esp32c2.cfg b/tcl/target/esp32c2.cfg
new file mode 100644
index 000000000..a22fe7088
--- /dev/null
+++ b/tcl/target/esp32c2.cfg
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+# Source the ESP common configuration file.
+source [find target/esp_common.cfg]
+
+# Target specific global variables
+set _CHIPNAME "esp32c2"
+set _CPUTAPID "0x0000cc25"
+set _ESP_ARCH "riscv"
+set _ONLYCPU 1
+set _ESP_SMP_TARGET 0
+set _ESP_SMP_BREAK 0
+set _ESP_EFUSE_MAC_ADDR_REG 0x60008840
+
+# Target specific functions should be implemented for each riscv chips.
+proc esp32c2_wdt_disable { } {
+ # Halt event can occur during config phase (before "init" is done).
+ # Ignore it since mww commands don't work at that time.
+ if { [string compare [command mode] config] == 0 } {
+ return
+ }
+
+ # Disable Timer Group 0 WDT
+ mww 0x6001f064 0x50D83AA1
+ mww 0x6001F048 0
+ # Clear TG0 wdt interrupt state
+ mww 0x6001F07C 0x2
+
+ # Disable RTC WDT
+ mww 0x6000809C 0x50D83AA1
+ mww 0x60008084 0
+
+ # Disable Super WDT
+ mww 0x600080A4 0x8F1D312A
+ mww 0x600080A0 0x84B00000
+
+ # Clear RTC and Super wdt interrupt states
+ mww 0x60008044 0x8008
+}
+
+proc esp32c2_soc_reset { } {
+ global _RISCV_DMCONTROL
+
+ # This procedure does "digital system reset", i.e. resets
+ # all the peripherals except for the RTC block.
+ # It is called from reset-assert-post target event callback,
+ # after assert_reset procedure was called.
+ # Since we need the hart to execute a write to RTC_CNTL_SW_SYS_RST,
+ # temporarily take it out of reset. Save the dmcontrol state before
+ # doing so.
+ riscv dmi_write $_RISCV_DMCONTROL 0x80000001
+ # Trigger the reset
+ mww 0x60008000 0x9c00a000
+ # Workaround for stuck in cpu start during calibration.
+ # By writing zero to TIMG_RTCCALICFG_REG, we are disabling calibration
+ mww 0x6001F068 0
+ # Wait for the reset to happen
+ sleep 10
+ poll
+ # Disable the watchdogs again
+ esp32c2_wdt_disable
+
+ # Here debugger reads allresumeack and allhalted bits as set (0x330a2)
+ # We will clean allhalted state by resuming the core.
+ riscv dmi_write $_RISCV_DMCONTROL 0x40000001
+
+ # Put the hart back into reset state. Note that we need to keep haltreq set.
+ riscv dmi_write $_RISCV_DMCONTROL 0x80000003
+}
+
+proc esp32c2_memprot_is_enabled { } {
+ global _RISCV_ABS_CMD _RISCV_ABS_DATA0
+
+ #Â PMPADDR 0-1 covers entire valid IRAM range and PMPADDR 2-3 covers entire DRAM region
+ # pmpcfg0 holds the configuration for the PMP 0-3 address registers
+
+ # read pmpcfg0 and extract into 8-bit variables.
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203a0
+ set pmpcfg0 [riscv dmi_read $_RISCV_ABS_DATA0]
+
+ set pmp0cfg [expr {($pmpcfg0 >> (8 * 0)) & 0xFF}]
+ set pmp1cfg [expr {($pmpcfg0 >> (8 * 1)) & 0xFF}]
+ set pmp2cfg [expr {($pmpcfg0 >> (8 * 2)) & 0xFF}]
+ set pmp3cfg [expr {($pmpcfg0 >> (8 * 3)) & 0xFF}]
+
+ # read PMPADDR 0-3
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b0
+ set pmpaddr0 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b1
+ set pmpaddr1 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b2
+ set pmpaddr2 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b3
+ set pmpaddr3 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+
+ set IRAM_LOW 0x40380000
+ set IRAM_HIGH 0x403C0000
+ set DRAM_LOW 0x3FCA0000
+ set DRAM_HIGH 0x3FCE0000
+ set PMP_RWX 0x07
+ set PMP_RW 0x03
+
+ # The lock bit remains unset during the execution of the 2nd stage bootloader.
+ #Â Thus we do not perform a lock bit check for IRAM and DRAM regions.
+
+ # Check OpenOCD can write and execute from IRAM.
+ if {$pmpaddr0 >= $IRAM_LOW && $pmpaddr1 <= $IRAM_HIGH} {
+ if {($pmp0cfg & $PMP_RWX) != 0 || ($pmp1cfg & $PMP_RWX) != $PMP_RWX} {
+ return 1
+ }
+ }
+
+ # Check OpenOCD can read/write entire DRAM region.
+ if {$pmpaddr2 >= $DRAM_LOW && $pmpaddr3 <= $DRAM_HIGH} {
+ if {($pmp2cfg & $PMP_RW) != 0 && ($pmp3cfg & $PMP_RW) != $PMP_RW} {
+ return 1
+ }
+ }
+
+ return 0
+}
+
+create_esp_target $_ESP_ARCH
diff --git a/tcl/target/esp32c3.cfg b/tcl/target/esp32c3.cfg
new file mode 100644
index 000000000..fea14d7c7
--- /dev/null
+++ b/tcl/target/esp32c3.cfg
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+# Source the ESP common configuration file.
+source [find target/esp_common.cfg]
+
+# Target specific global variables
+set _CHIPNAME "esp32c3"
+set _CPUTAPID "0x00005c25"
+set _ESP_ARCH "riscv"
+set _ONLYCPU 1
+set _ESP_SMP_TARGET 0
+set _ESP_SMP_BREAK 0
+set _ESP_EFUSE_MAC_ADDR_REG 0x60008844
+
+# Target specific functions should be implemented for each riscv chips.
+proc esp32c3_wdt_disable { } {
+ # Halt event can occur during config phase (before "init" is done).
+ # Ignore it since mww commands don't work at that time.
+ if { [string compare [command mode] config] == 0 } {
+ return
+ }
+
+ # Disable Timer Group 0 WDT
+ mww 0x6001f064 0x50D83AA1
+ mww 0x6001F048 0
+ # Clear TG0 wdt interrupt state
+ mww 0x6001F07C 0x2
+
+ # Disable Timer Group 1 WDT
+ mww 0x60020064 0x50D83AA1
+ mww 0x60020048 0
+ # Clear TG1 wdt interrupt state
+ mww 0x6002007C 0x2
+
+ # Disable RTC WDT
+ mww 0x600080a8 0x50D83AA1
+ mww 0x60008090 0
+
+ # Disable Super WDT
+ mww 0x600080b0 0x8F1D312A
+ mww 0x600080ac 0x84B00000
+
+ # Clear RTC and Super wdt interrupt states
+ mww 0x6000804C 0x8008
+}
+
+# This is almost identical with the esp32c2_soc_reset.
+#Â Will be refactored with the other common settings.
+proc esp32c3_soc_reset { } {
+ global _RISCV_DMCONTROL
+
+ # This procedure does "digital system reset", i.e. resets
+ # all the peripherals except for the RTC block.
+ # It is called from reset-assert-post target event callback,
+ # after assert_reset procedure was called.
+ # Since we need the hart to execute a write to RTC_CNTL_SW_SYS_RST,
+ # temporarily take it out of reset. Save the dmcontrol state before
+ # doing so.
+ riscv dmi_write $_RISCV_DMCONTROL 0x80000001
+ # Trigger the reset
+ mww 0x60008000 0x9c00a000
+ # Workaround for stuck in cpu start during calibration.
+ # By writing zero to TIMG_RTCCALICFG_REG, we are disabling calibration
+ mww 0x6001F068 0
+ # Wait for the reset to happen
+ sleep 10
+ poll
+ # Disable the watchdogs again
+ esp32c3_wdt_disable
+
+ # Here debugger reads allresumeack and allhalted bits as set (0x330a2)
+ # We will clean allhalted state by resuming the core.
+ riscv dmi_write $_RISCV_DMCONTROL 0x40000001
+
+ # Put the hart back into reset state. Note that we need to keep haltreq set.
+ riscv dmi_write $_RISCV_DMCONTROL 0x80000003
+}
+
+proc esp32c3_memprot_is_enabled { } {
+ # IRAM0 PMS lock, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_0_REG
+ if { [get_mmr_bit 0x600C10A8 0] != 0 } {
+ return 1
+ }
+ # DRAM0 PMS lock, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_0_REG
+ if { [get_mmr_bit 0x600C10C0 0] != 0 } {
+ return 1
+ }
+ return 0
+}
+
+create_esp_target $_ESP_ARCH
diff --git a/tcl/target/esp32c6.cfg b/tcl/target/esp32c6.cfg
new file mode 100644
index 000000000..4299a0b55
--- /dev/null
+++ b/tcl/target/esp32c6.cfg
@@ -0,0 +1,152 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+# Source the ESP common configuration file.
+source [find target/esp_common.cfg]
+
+# Target specific global variables
+set _CHIPNAME "esp32c6"
+set _CPUTAPID 0x0000dc25
+set _ESP_ARCH "riscv"
+set _ONLYCPU 1
+set _ESP_SMP_TARGET 0
+set _ESP_SMP_BREAK 0
+set _ESP_EFUSE_MAC_ADDR_REG 0x600B0844
+
+# Target specific functions should be implemented for each riscv chips.
+proc esp32c6_wdt_disable { } {
+ # Halt event can occur during config phase (before "init" is done).
+ # Ignore it since mww commands don't work at that time.
+ if { [string compare [command mode] config] == 0 } {
+ return
+ }
+
+ # Disable Timer Group 0 WDT
+ mww 0x60008064 0x50D83AA1
+ mww 0x60008048 0
+ # Clear TG0 wdt interrupt state
+ mww 0x6000807C 0x2
+
+ # Disable Timer Group 1 WDT
+ mww 0x60009064 0x50D83AA1
+ mww 0x60009048 0
+ # Clear TG1 wdt interrupt state
+ mww 0x6000907C 0x2
+
+ # Disable LP_WDT_RTC
+ mww 0x600b1c18 0x50D83AA1
+ mww 0x600B1c00 0
+ # Disable LP_WDT_SWD
+ mww 0x600b1c20 0x50D83AA1
+ mww 0x600b1c1c 0x40000000
+
+ # Clear LP_WDT_RTC and LP_WDT_SWD interrupt states
+ mww 0x600B1c30 0xC0000000
+}
+
+proc esp32c6_soc_reset { } {
+ global _RISCV_DMCONTROL _RISCV_SB_CS _RISCV_SB_ADDR0 _RISCV_SB_DATA0
+
+ riscv dmi_write $_RISCV_DMCONTROL 0x80000001
+ riscv dmi_write $_RISCV_SB_CS 0x48000
+ riscv dmi_write $_RISCV_SB_ADDR0 0x600b1034
+ riscv dmi_write $_RISCV_SB_DATA0 0x80000000
+ # clear dmactive to clear sbbusy otherwise debug module gets stuck
+ riscv dmi_write $_RISCV_DMCONTROL 0
+
+ riscv dmi_write $_RISCV_SB_CS 0x48000
+ riscv dmi_write $_RISCV_SB_ADDR0 0x600b1038
+ riscv dmi_write $_RISCV_SB_DATA0 0x10000000
+
+ # clear dmactive to clear sbbusy otherwise debug module gets stuck
+ riscv dmi_write $_RISCV_DMCONTROL 0
+ riscv dmi_write $_RISCV_DMCONTROL 0x40000001
+ # Here debugger reads dmstatus as 0xc03a2
+
+ # Wait for the reset to happen
+ sleep 10
+ poll
+ # Here debugger reads dmstatus as 0x3a2
+
+ # Disable the watchdogs again
+ esp32c6_wdt_disable
+
+ # Here debugger reads anyhalted and allhalted bits as set (0x3a2)
+ # We will clean allhalted state by resuming the core.
+ riscv dmi_write $_RISCV_DMCONTROL 0x40000001
+
+ # Put the hart back into reset state. Note that we need to keep haltreq set.
+ riscv dmi_write $_RISCV_DMCONTROL 0x80000003
+}
+
+proc esp32c6_memprot_is_enabled { } {
+ global _RISCV_ABS_CMD _RISCV_ABS_DATA0
+
+ # If IRAM/DRAM split is enabled TOR address match mode is used.
+ # If IRAM/DRAM split is disabled NAPOT mode is used.
+ #Â In order to determine if the IRAM/DRAM regions are protected against RWX/RW,
+ #Â it is necessary to first read the mode and then apply the appropriate method for checking.
+ #Â We can understand the mode reading pmp5cfg in pmpcfg1 register.
+ # If it is none we know that pmp6cfg and pmp7cfg is in TOR mode.
+
+ # Read pmpcfg1 and extract into 8-bit variables.
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203a1
+ set pmpcfg1 [riscv dmi_read $_RISCV_ABS_DATA0]
+
+ set pmp5cfg [expr {($pmpcfg1 >> (8 * 1)) & 0xFF}]
+ set pmp6cfg [expr {($pmpcfg1 >> (8 * 2)) & 0xFF}]
+ set pmp7cfg [expr {($pmpcfg1 >> (8 * 3)) & 0xFF}]
+
+ set IRAM_LOW 0x40800000
+ set IRAM_HIGH 0x40880000
+ set DRAM_LOW 0x40800000
+ set DRAM_HIGH 0x40880000
+ set PMP_RWX 0x07
+ set PMP_RW 0x03
+ set PMP_A [expr {($pmp5cfg >> 3) & 0x03}]
+
+ if {$PMP_A == 0} {
+ #Â TOR mode used to protect valid address space.
+
+ # Read PMPADDR 5-7
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b5
+ set pmpaddr5 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b6
+ set pmpaddr6 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b7
+ set pmpaddr7 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+
+ # The lock bit remains unset during the execution of the 2nd stage bootloader.
+ #Â Thus we do not perform a lock bit check for IRAM and DRAM regions.
+
+ # Check OpenOCD can write and execute from IRAM.
+ if {$pmpaddr5 >= $IRAM_LOW && $pmpaddr6 <= $IRAM_HIGH} {
+ if {($pmp5cfg & $PMP_RWX) != 0 || ($pmp6cfg & $PMP_RWX) != $PMP_RWX} {
+ return 1
+ }
+ }
+
+ # Check OpenOCD can read/write entire DRAM region.
+ if {$pmpaddr7 >= $DRAM_LOW && $pmpaddr7 <= $DRAM_HIGH} {
+ if {($pmp7cfg & $PMP_RW) != $PMP_RW} {
+ return 1
+ }
+ }
+ } elseif {$PMP_A == 3} {
+ # NAPOT mode used to protect valid address space.
+
+ # Read PMPADDR 5
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b5
+ set pmpaddr5 [expr {[riscv dmi_read $_RISCV_ABS_DATA0]}]
+
+ #Â Expected value written to the pmpaddr5
+ set pmpaddr_napot [expr {($IRAM_LOW | (($IRAM_HIGH - $IRAM_LOW - 1) >> 1)) >> 2}]
+ if {($pmpaddr_napot != $pmpaddr5) || ($pmp5cfg & $PMP_RWX) != $PMP_RWX} {
+ return 1
+ }
+ }
+
+ return 0
+}
+
+create_esp_target $_ESP_ARCH
diff --git a/tcl/target/esp32h2.cfg b/tcl/target/esp32h2.cfg
new file mode 100644
index 000000000..4d3e9350b
--- /dev/null
+++ b/tcl/target/esp32h2.cfg
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+# Source the ESP common configuration file.
+source [find target/esp_common.cfg]
+
+# Target specific global variables
+set _CHIPNAME "esp32h2"
+set _CPUTAPID 0x00010c25
+set _ESP_ARCH "riscv"
+set _ONLYCPU 1
+set _ESP_SMP_TARGET 0
+set _ESP_SMP_BREAK 0
+set _ESP_EFUSE_MAC_ADDR_REG 0x600B0844
+
+# Target specific functions should be implemented for each riscv chips.
+proc esp32h2_wdt_disable { } {
+ # Halt event can occur during config phase (before "init" is done).
+ # Ignore it since mww commands don't work at that time.
+ if { [string compare [command mode] config] == 0 } {
+ return
+ }
+
+ # Disable Timer Group 0 WDT
+ mww 0x60009064 0x50D83AA1
+ mww 0x60009048 0
+ # Clear TG0 wdt interrupt state
+ mww 0x6000907C 0x2
+
+ # Disable Timer Group 1 WDT
+ mww 0x6000A064 0x50D83AA1
+ mww 0x6000A048 0
+ # Clear TG1 wdt interrupt state
+ mww 0x6000A07C 0x2
+}
+
+proc esp32h2_soc_reset { } {
+ global _RISCV_DMCONTROL _RISCV_SB_CS _RISCV_SB_ADDR0 _RISCV_SB_DATA0
+
+ riscv dmi_write $_RISCV_DMCONTROL 0x80000001
+ riscv dmi_write $_RISCV_SB_CS 0x48000
+ riscv dmi_write $_RISCV_SB_ADDR0 0x600b1034
+ riscv dmi_write $_RISCV_SB_DATA0 0x80000000
+ # clear dmactive to clear sbbusy otherwise debug module gets stuck
+ riscv dmi_write $_RISCV_DMCONTROL 0
+
+ riscv dmi_write $_RISCV_SB_CS 0x48000
+ riscv dmi_write $_RISCV_SB_ADDR0 0x600b1038
+ riscv dmi_write $_RISCV_SB_DATA0 0x10000000
+
+ # clear dmactive to clear sbbusy otherwise debug module gets stuck
+ riscv dmi_write $_RISCV_DMCONTROL 0
+ riscv dmi_write $_RISCV_DMCONTROL 0x40000001
+ # Here debugger reads dmstatus as 0xc03a2
+
+ # Wait for the reset to happen
+ sleep 10
+ poll
+ # Here debugger reads dmstatus as 0x3a2
+
+ # Disable the watchdogs again
+ esp32h2_wdt_disable
+
+ # Here debugger reads anyhalted and allhalted bits as set (0x3a2)
+ # We will clean allhalted state by resuming the core.
+ riscv dmi_write $_RISCV_DMCONTROL 0x40000001
+
+ # Put the hart back into reset state. Note that we need to keep haltreq set.
+ riscv dmi_write $_RISCV_DMCONTROL 0x80000003
+}
+
+proc esp32h2_memprot_is_enabled { } {
+ global _RISCV_ABS_CMD _RISCV_ABS_DATA0
+ #Â If IRAM/DRAM split is enabled;
+ # PMPADDR 5-6 will cover valid IRAM region;
+ # PMPADDR 7 will cover valid DRAM region;
+ # Only TOR mode is used for IRAM and DRAM protections.
+
+ # Read pmpcfg1 and extract into 8-bit variables.
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203a1
+ set pmpcfg1 [riscv dmi_read $_RISCV_ABS_DATA0]
+
+ set pmp5cfg [expr {($pmpcfg1 >> (8 * 1)) & 0xFF}]
+ set pmp6cfg [expr {($pmpcfg1 >> (8 * 2)) & 0xFF}]
+ set pmp7cfg [expr {($pmpcfg1 >> (8 * 3)) & 0xFF}]
+
+ # Read PMPADDR 5-7
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b5
+ set pmpaddr5 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b6
+ set pmpaddr6 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+ riscv dmi_write $_RISCV_ABS_CMD 0x2203b7
+ set pmpaddr7 [expr {[riscv dmi_read $_RISCV_ABS_DATA0] << 2}]
+
+ set IRAM_LOW 0x40800000
+ set IRAM_HIGH 0x40850000
+ set DRAM_LOW 0x40800000
+ set DRAM_HIGH 0x40850000
+
+ set PMP_RWX 0x07
+ set PMP_RW 0x03
+
+ # The lock bit remains unset during the execution of the 2nd stage bootloader.
+ #Â Thus, we do not perform a lock bit check for IRAM and DRAM regions.
+
+ # Check OpenOCD can write and execute from IRAM.
+ if {$pmpaddr5 >= $IRAM_LOW && $pmpaddr6 <= $IRAM_HIGH} {
+ if {($pmp5cfg & $PMP_RWX) != 0 || ($pmp6cfg & $PMP_RWX) != $PMP_RWX} {
+ return 1
+ }
+ }
+
+ # Check OpenOCD can read/write entire DRAM region.
+ #Â If IRAM/DRAM split is disabled, pmpaddr7 will be zero, checking only IRAM region is enough.
+ if {$pmpaddr7 != 0 && $pmpaddr7 >= $DRAM_LOW && $pmpaddr7 <= $DRAM_HIGH} {
+ if {($pmp7cfg & $PMP_RW) != $PMP_RW} {
+ return 1
+ }
+ }
+
+ return 0
+}
+
+create_esp_target $_ESP_ARCH
diff --git a/tcl/target/esp32s2.cfg b/tcl/target/esp32s2.cfg
index 4c1362a34..05b4b29f9 100644
--- a/tcl/target/esp32s2.cfg
+++ b/tcl/target/esp32s2.cfg
@@ -5,13 +5,13 @@
source [find target/esp_common.cfg]
# Target specific global variables
-set _CHIPNAME "esp32s2"
-set _CPUTAPID 0x120034e5
-set _ESP_ARCH "xtensa"
-set _ONLYCPU 1
-set _ESP_SMP_TARGET 0
-set _ESP_SMP_BREAK 1
-set _ESP_EFUSE_MAC_ADDR_REG 0x3f41A004
+set _CHIPNAME "esp32s2"
+set _CPUTAPID 0x120034e5
+set _ESP_ARCH "xtensa"
+set _ONLYCPU 1
+set _ESP_SMP_TARGET 0
+set _ESP_SMP_BREAK 1
+set _ESP_EFUSE_MAC_ADDR_REG 0x3f41A004
proc esp32s2_memprot_is_enabled { } {
# IRAM0, DPORT_PMS_PRO_IRAM0_0_REG
diff --git a/tcl/target/esp32s3.cfg b/tcl/target/esp32s3.cfg
index 12c166c46..53a9742d6 100644
--- a/tcl/target/esp32s3.cfg
+++ b/tcl/target/esp32s3.cfg
@@ -5,13 +5,13 @@
source [find target/esp_common.cfg]
# Target specific global variables
-set _CHIPNAME "esp32s3"
-set _CPUTAPID 0x120034e5
-set _ESP_ARCH "xtensa"
-set _ONLYCPU 3
-set _ESP_SMP_TARGET 1
-set _ESP_SMP_BREAK 1
-set _ESP_EFUSE_MAC_ADDR_REG 0x60007044
+set _CHIPNAME "esp32s3"
+set _CPUTAPID 0x120034e5
+set _ESP_ARCH "xtensa"
+set _ONLYCPU 3
+set _ESP_SMP_TARGET 1
+set _ESP_SMP_BREAK 1
+set _ESP_EFUSE_MAC_ADDR_REG 0x60007044
if { [info exists ESP32_S3_ONLYCPU] } {
set _ONLYCPU $ESP32_S3_ONLYCPU
diff --git a/tcl/target/esp_common.cfg b/tcl/target/esp_common.cfg
index e9a188f9f..f0aafa805 100644
--- a/tcl/target/esp_common.cfg
+++ b/tcl/target/esp_common.cfg
@@ -6,6 +6,14 @@ source [find bitsbytes.tcl]
source [find memory.tcl]
source [find mmr_helpers.tcl]
+# Riscv Debug Module Registers which are used around esp configuration files.
+set _RISCV_ABS_DATA0 0x04
+set _RISCV_DMCONTROL 0x10
+set _RISCV_ABS_CMD 0x17
+set _RISCV_SB_CS 0x38
+set _RISCV_SB_ADDR0 0x39
+set _RISCV_SB_DATA0 0x3C
+
# Common ESP chips definitions
# Espressif supports only NuttX in the upstream.
@@ -25,24 +33,31 @@ proc set_esp_common_variables { } {
global _CHIPNAME _ONLYCPU _ESP_SMP_TARGET
global _CPUNAME_0 _CPUNAME_1 _TARGETNAME_0 _TARGETNAME_1 _TAPNAME_0 _TAPNAME_1
global _ESP_WDT_DISABLE _ESP_SOC_RESET _ESP_MEMPROT_IS_ENABLED
+ global _TARGET_TYPE _ESP_ARCH
# For now we support dual core at most.
if { $_ONLYCPU == 1 && $_ESP_SMP_TARGET == 0} {
- set _TARGETNAME_0 $_CHIPNAME
- set _CPUNAME_0 cpu
- set _TAPNAME_0 $_CHIPNAME.$_CPUNAME_0
+ set _TARGETNAME_0 $_CHIPNAME
+ set _CPUNAME_0 cpu
+ set _TAPNAME_0 $_CHIPNAME.$_CPUNAME_0
+ } else {
+ set _CPUNAME_0 cpu0
+ set _CPUNAME_1 cpu1
+ set _TARGETNAME_0 $_CHIPNAME.$_CPUNAME_0
+ set _TARGETNAME_1 $_CHIPNAME.$_CPUNAME_1
+ set _TAPNAME_0 $_TARGETNAME_0
+ set _TAPNAME_1 $_TARGETNAME_1
+ }
+
+ if {$_ESP_ARCH == "riscv"} {
+ set _TARGET_TYPE $_ESP_ARCH
} else {
- set _CPUNAME_0 cpu0
- set _CPUNAME_1 cpu1
- set _TARGETNAME_0 $_CHIPNAME.$_CPUNAME_0
- set _TARGETNAME_1 $_CHIPNAME.$_CPUNAME_1
- set _TAPNAME_0 $_TARGETNAME_0
- set _TAPNAME_1 $_TARGETNAME_1
+ set _TARGET_TYPE $_CHIPNAME
}
- set _ESP_WDT_DISABLE "${_CHIPNAME}_wdt_disable"
- set _ESP_SOC_RESET "${_CHIPNAME}_soc_reset"
- set _ESP_MEMPROT_IS_ENABLED "${_CHIPNAME}_memprot_is_enabled"
+ set _ESP_WDT_DISABLE "${_CHIPNAME}_wdt_disable"
+ set _ESP_SOC_RESET "${_CHIPNAME}_soc_reset"
+ set _ESP_MEMPROT_IS_ENABLED "${_CHIPNAME}_memprot_is_enabled"
}
proc create_esp_jtag { } {
@@ -56,11 +71,11 @@ proc create_esp_jtag { } {
}
proc create_openocd_targets { } {
- global _TARGETNAME_0 _TARGETNAME_1 _TAPNAME_0 _TAPNAME_1 _RTOS _CHIPNAME _ONLYCPU
+ global _TARGETNAME_0 _TARGETNAME_1 _TAPNAME_0 _TAPNAME_1 _RTOS _CHIPNAME _ONLYCPU _TARGET_TYPE
- target create $_TARGETNAME_0 $_CHIPNAME -chain-position $_TAPNAME_0 -coreid 0 -rtos $_RTOS
+ target create $_TARGETNAME_0 $_TARGET_TYPE -chain-position $_TAPNAME_0 -coreid 0 -rtos $_RTOS
if { $_ONLYCPU != 1 } {
- target create $_TARGETNAME_1 $_CHIPNAME -chain-position $_TAPNAME_1 -coreid 1 -rtos $_RTOS
+ target create $_TARGETNAME_1 $_TARGET_TYPE -chain-position $_TAPNAME_1 -coreid 1 -rtos $_RTOS
target smp $_TARGETNAME_0 $_TARGETNAME_1
}
}
@@ -69,13 +84,12 @@ proc create_esp_target { ARCH } {
set_esp_common_variables
create_esp_jtag
create_openocd_targets
- configure_openocd_events
+ configure_openocd_events $ARCH
if { $ARCH == "xtensa"} {
configure_esp_xtensa_default_settings
} else {
- #Â riscv targets are not upstreamed yet.
- # they can be found at the official Espressif fork.
+ configure_esp_riscv_default_settings
}
}
@@ -131,7 +145,6 @@ proc configure_event_halted { } {
$_TARGETNAME_0 configure -event halted {
global _ESP_WDT_DISABLE
$_ESP_WDT_DISABLE
- esp halted_event_handler
}
}
@@ -167,12 +180,25 @@ proc configure_event_gdb_attach { } {
}
}
-proc configure_openocd_events { } {
+proc configure_openocd_events { ARCH } {
+ if { $ARCH == "riscv" } {
+ configure_event_halted
+ }
configure_event_examine_end
configure_event_reset_assert_post
configure_event_gdb_attach
}
+proc configure_esp_riscv_default_settings { } {
+ gdb breakpoint_override hard
+ riscv set_reset_timeout_sec 2
+ riscv set_command_timeout_sec 5
+ riscv set_mem_access sysbus progbuf abstract
+ riscv set_ebreakm on
+ riscv set_ebreaks on
+ riscv set_ebreaku on
+}
+
proc configure_esp_xtensa_default_settings { } {
global _TARGETNAME_0 _ESP_SMP_BREAK _FLASH_VOLTAGE _CHIPNAME
-----------------------------------------------------------------------
Summary of changes:
doc/openocd.texi | 8 +-
tcl/board/{esp32s3-ftdi.cfg => esp32c2-ftdi.cfg} | 10 +-
tcl/board/esp32c3-builtin.cfg | 15 +++
tcl/board/{esp32s3-ftdi.cfg => esp32c3-ftdi.cfg} | 10 +-
tcl/board/esp32c6-builtin.cfg | 15 +++
tcl/board/esp32h2-builtin.cfg | 15 +++
tcl/interface/esp_usb_jtag.cfg | 2 +
tcl/interface/ftdi/esp32_devkitj_v1.cfg | 2 +
tcl/interface/ftdi/esp32s2_kaluga_v1.cfg | 2 +
tcl/target/esp32.cfg | 16 +--
tcl/target/esp32c2.cfg | 124 ++++++++++++++++++
tcl/target/esp32c3.cfg | 92 ++++++++++++++
tcl/target/esp32c6.cfg | 152 +++++++++++++++++++++++
tcl/target/esp32h2.cfg | 124 ++++++++++++++++++
tcl/target/esp32s2.cfg | 14 +--
tcl/target/esp32s3.cfg | 14 +--
tcl/target/esp_common.cfg | 66 +++++++---
17 files changed, 627 insertions(+), 54 deletions(-)
copy tcl/board/{esp32s3-ftdi.cfg => esp32c2-ftdi.cfg} (68%)
create mode 100644 tcl/board/esp32c3-builtin.cfg
copy tcl/board/{esp32s3-ftdi.cfg => esp32c3-ftdi.cfg} (68%)
create mode 100644 tcl/board/esp32c6-builtin.cfg
create mode 100644 tcl/board/esp32h2-builtin.cfg
create mode 100644 tcl/target/esp32c2.cfg
create mode 100644 tcl/target/esp32c3.cfg
create mode 100644 tcl/target/esp32c6.cfg
create mode 100644 tcl/target/esp32h2.cfg
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-08 15:57:37
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 52ea420dd2d662d00c25621ccb9d3af647d28d4f (commit)
from 1afb3e75f003d3b2a1bf76fde8797a1ea8312189 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 52ea420dd2d662d00c25621ccb9d3af647d28d4f
Author: Daniel Anselmi <dan...@gm...>
Date: Sat Dec 28 02:22:51 2024 +0100
ipdbg: simplify command chains
simplify ipdbg commands:
$hub_name ipdbg start -> $hub_name start
ipdbg/fix: While there, handle the multi-word deprecated commands
by adding quotes.
Change-Id: I5a56df2dbf2a5710442242727fa9384e5541ed53
Signed-off-by: Daniel Anselmi <dan...@gm...>
Fixes: https://sourceforge.net/p/openocd/tickets/434/
Reported-by: Evgeniy Naydanov <evg...@sy...>
Reviewed-on: https://review.openocd.org/c/openocd/+/8873
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 9540e69f3..2202a8d98 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -12675,7 +12675,7 @@ If your device/vendor is not supported you have to use the first variant.
@end deffn
-@deffn {Command} {$hub_name ipdbg start} @option{-tool @var{number}} @option{-port @var{number}}
+@deffn {Command} {$hub_name start} @option{-tool @var{number}} @option{-port @var{number}}
Starts a IPDBG JTAG-Host server. The remaining arguments can be specified in any order.
Command options:
@@ -12685,7 +12685,7 @@ Command options:
@end itemize
@end deffn
-@deffn {Command} {$hub_name ipdbg stop} @option{-tool @var{number}}
+@deffn {Command} {$hub_name stop} @option{-tool @var{number}}
Stops a IPDBG JTAG-Host server.
Command options:
@itemize @bullet
@@ -12696,21 +12696,21 @@ Command options:
Examples:
@example
ipdbg create-hub xc6s.ipdbghub -tap xc6s.tap -hub 0x02
-xc6s.ipdbghub ipdbg start -port 4242 -tool 4
+xc6s.ipdbghub start -port 4242 -tool 4
@end example
Creates a IPDBG Hub and starts a server listening on tcp-port 4242 which connects to tool 4.
The connection is through the TAP of a Xilinx Spartan 6 on USER1 instruction (tested with a papillion pro board).
@example
ipdbg create-hub max10m50.ipdbghub -tap max10m50.tap -hub 0x00C -vir
-max10m50.ipdbghub ipdbg start -tool 1 -port 60000
+max10m50.ipdbghub start -tool 1 -port 60000
@end example
Starts a server listening on tcp-port 60000 which connects to tool 1 (data_up_1/data_down_1).
The connection is through the TAP of a Intel MAX10 virtual jtag component (sld_instance_index is 0; sld_ir_width is smaller than 5).
@example
ipdbg create-hub xc7.ipdbghub -pld xc7.pld
-xc7.ipdbghub ipdbg start -port 5555 -tool 0
+xc7.ipdbghub start -port 5555 -tool 0
@end example
Starts a server listening on tcp-port 5555 which connects to tool 0 (data_up_0/data_down_0).
The TAP and ir value used to reach the JTAG Hub is given by the pld driver.
diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl
index 5c466c628..f24e57ab0 100644
--- a/src/jtag/startup.tcl
+++ b/src/jtag/startup.tcl
@@ -1205,7 +1205,7 @@ proc "pld device" {driver tap_name {opt 0}} {
lappend _telnet_autocomplete_skip "ipdbg -start"
proc "ipdbg -start" {args} {
- echo "DEPRECATED! use 'ipdbg create-hub' and 'chip.ipdbghub ipdbg start ...', not 'ipdbg -start ...'"
+ echo "DEPRECATED! use 'ipdbg create-hub' and 'chip.ipdbghub start ...', not 'ipdbg -start ...'"
set tap_name ""
set pld_name ""
set tool_num "1"
@@ -1271,17 +1271,14 @@ proc "ipdbg -start" {args} {
return
}
- echo "name: $hub_name"
- echo "ipdbg create-hub $hub_name $args"
-
catch {eval ipdbg create-hub $hub_name $args}
- eval $hub_name ipdbg start -tool $tool_num -port $port_num
+ eval $hub_name start -tool $tool_num -port $port_num
}
lappend _telnet_autocomplete_skip "ipdbg -stop"
proc "ipdbg -stop" {args} {
- echo "DEPRECATED! use 'chip.ipdbghub ipdbg stop ...', not 'ipdbg -stop ...'"
+ echo "DEPRECATED! use 'chip.ipdbghub stop ...', not 'ipdbg -stop ...'"
set tap_name ""
set pld_name ""
set tool_num "1"
@@ -1328,7 +1325,11 @@ proc "ipdbg -stop" {args} {
return
}
- eval $hub_name ipdbg stop -tool $tool_num
+ eval $hub_name stop -tool $tool_num
+}
+
+proc ipdbg {cmd args} {
+ tailcall "ipdbg $cmd" {*}$args
}
# END MIGRATION AIDS
diff --git a/src/server/ipdbg.c b/src/server/ipdbg.c
index 859fdb035..466717c46 100644
--- a/src/server/ipdbg.c
+++ b/src/server/ipdbg.c
@@ -885,23 +885,6 @@ COMMAND_HANDLER(handle_ipdbg_stop_command)
return ipdbg_stop(hub, tool);
}
-static const struct command_registration ipdbg_hostserver_subcommand_handlers[] = {
- {
- .name = "start",
- .mode = COMMAND_EXEC,
- .handler = handle_ipdbg_start_command,
- .help = "Starts a IPDBG Host server.",
- .usage = "-tool number -port port"
- }, {
- .name = "stop",
- .mode = COMMAND_EXEC,
- .handler = handle_ipdbg_stop_command,
- .help = "Stops a IPDBG Host server.",
- .usage = "-tool number"
- },
- COMMAND_REGISTRATION_DONE
-};
-
static COMMAND_HELPER(ipdbg_config_queuing, struct ipdbg_hub *hub, unsigned int size)
{
if (!hub)
@@ -944,13 +927,18 @@ COMMAND_HANDLER(handle_ipdbg_cfg_queuing_command)
static const struct command_registration ipdbg_hub_subcommand_handlers[] = {
{
- .name = "ipdbg",
+ .name = "start",
.mode = COMMAND_EXEC,
- .help = "IPDBG Hub commands.",
- .usage = "",
- .chain = ipdbg_hostserver_subcommand_handlers
- },
- {
+ .handler = handle_ipdbg_start_command,
+ .help = "Starts a IPDBG Host server.",
+ .usage = "-tool number -port port"
+ }, {
+ .name = "stop",
+ .mode = COMMAND_EXEC,
+ .handler = handle_ipdbg_stop_command,
+ .help = "Stops a IPDBG Host server.",
+ .usage = "-tool number"
+ }, {
.name = "queuing",
.handler = handle_ipdbg_cfg_queuing_command,
.mode = COMMAND_ANY,
@@ -1151,7 +1139,6 @@ static const struct command_registration ipdbg_command_handlers[] = {
},
COMMAND_REGISTRATION_DONE
};
-
int ipdbg_register_commands(struct command_context *cmd_ctx)
{
return register_commands(cmd_ctx, NULL, ipdbg_command_handlers);
diff --git a/tcl/board/bemicro_cycloneiii.cfg b/tcl/board/bemicro_cycloneiii.cfg
index 3c92b500c..591a07047 100644
--- a/tcl/board/bemicro_cycloneiii.cfg
+++ b/tcl/board/bemicro_cycloneiii.cfg
@@ -18,7 +18,7 @@ source [find fpga/altera-cycloneiii.cfg]
#openocd -f board/bemicro_cycloneiii.cfg -c "init" -c "pld load cycloneiii.pld cycloneiii_blinker.rbf"
# "ipdbg create-hub cycloneiii.ipdbghub -tap cycloneiii.tap -ir 0x00e"
-# "cycloneiii.ipdbghub ipdbg start -tool 0 -port 5555"
+# "cycloneiii.ipdbghub start -tool 0 -port 5555"
set JTAGSPI_CHAIN_ID cycloneiii.pld
diff --git a/tcl/board/digilent_cmod_s7.cfg b/tcl/board/digilent_cmod_s7.cfg
index 4fa45a17a..b975f9d37 100644
--- a/tcl/board/digilent_cmod_s7.cfg
+++ b/tcl/board/digilent_cmod_s7.cfg
@@ -16,7 +16,7 @@ adapter speed 10000
source [find cpld/xilinx-xc7.cfg]
# "ipdbg create-hub xc7.ipdbghub -tap xc7.tap -ir 0x02"
-# "xc7.ipdbghub ipdbg start -tool 0 -port 5555"
+# "xc7.ipdbghub start -tool 0 -port 5555"
#openocd -f board/digilent_cmod_s7.cfg -c "init" -c "pld load xc7.pld shared_folder/cmod_s7_fast.bit"
set JTAGSPI_CHAIN_ID xc7.pld
diff --git a/tcl/board/ecp5_evaluation.cfg b/tcl/board/ecp5_evaluation.cfg
index 71769f607..1aafac494 100644
--- a/tcl/board/ecp5_evaluation.cfg
+++ b/tcl/board/ecp5_evaluation.cfg
@@ -17,7 +17,7 @@ source [find fpga/lattice_ecp5.cfg]
#openocd -f board/ecp5_evaluation.cfg -c "init" -c "pld load ecp5.pld shared_folder/ecp5_blinker_impl1.bit"
#ipdbg create-hub ecp5.ipdbghub -tap ecp5.tap -ir 0x32
-#ecp5.ipdbghub ipdbg start -tool 0 -port 5555
+#ecp5.ipdbghub start -tool 0 -port 5555
set JTAGSPI_CHAIN_ID ecp5.pld
source [find cpld/jtagspi.cfg]
diff --git a/tcl/board/gowin_runber.cfg b/tcl/board/gowin_runber.cfg
index 6cb07362b..aaa316f7a 100644
--- a/tcl/board/gowin_runber.cfg
+++ b/tcl/board/gowin_runber.cfg
@@ -17,4 +17,4 @@ source [find fpga/gowin_gw1n.cfg]
#openocd -f board/gowin_runber.cfg -c "init" -c "pld load 0 impl/pnr/gw1n_blinker.fs"
#ipdbg create-hub gw1n.ipdbghub -tap gw1n.tap -ir 0x42
-#gw1n.ipdbghubipdbg start -tool 0 -port 5555
+#gw1n.ipdbghub start -tool 0 -port 5555
diff --git a/tcl/board/trion_t20_bga256.cfg b/tcl/board/trion_t20_bga256.cfg
index ca44f0b8c..572329ff6 100644
--- a/tcl/board/trion_t20_bga256.cfg
+++ b/tcl/board/trion_t20_bga256.cfg
@@ -21,7 +21,7 @@ source [find fpga/efinix_trion.cfg]
#openocd -f board/trion_t20_bga256.cfg -c "init" -c "pld load trion.pld outflow/trion_blinker.bit"
#ipdbg create-hub trion.ipdbghub -tap trion.tap -ir 0x8
-#trion.ipdbghub ipdbg start -tool 0 -port 5555
+#trion.ipdbghub start -tool 0 -port 5555
set JTAGSPI_CHAIN_ID trion.pld
source [find cpld/jtagspi.cfg]
-----------------------------------------------------------------------
Summary of changes:
doc/openocd.texi | 10 +++++-----
src/jtag/startup.tcl | 15 ++++++++-------
src/server/ipdbg.c | 35 +++++++++++------------------------
tcl/board/bemicro_cycloneiii.cfg | 2 +-
tcl/board/digilent_cmod_s7.cfg | 2 +-
tcl/board/ecp5_evaluation.cfg | 2 +-
tcl/board/gowin_runber.cfg | 2 +-
tcl/board/trion_t20_bga256.cfg | 2 +-
8 files changed, 29 insertions(+), 41 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-06 08:11:14
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 1afb3e75f003d3b2a1bf76fde8797a1ea8312189 (commit)
from 03b79387cce39fc2b88874f547dd3f9633b0b31b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 1afb3e75f003d3b2a1bf76fde8797a1ea8312189
Author: HAOUES Ahmed <ahm...@st...>
Date: Thu Oct 30 10:40:58 2025 +0100
tcl/target/stm32h7x: modify speed at OpenOCD initialization and
drop unneeded reset-init event
The speed is set to 1800 kHz at initialization, but increases to 4000 kHz
before flash programming, with debugging continuing at this higher speed.
So, setting 4000 kHz from the start makes sense.
Change-Id: I6bccb5837c624943212b727368b40153e42ccebb
Signed-off-by: HAOUES Ahmed <ahm...@st...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9027
Reviewed-by: Tomas Vanek <va...@fb...>
Tested-by: jenkins
diff --git a/tcl/target/stm32h7x.cfg b/tcl/target/stm32h7x.cfg
index 5aae93861..a364e0682 100644
--- a/tcl/target/stm32h7x.cfg
+++ b/tcl/target/stm32h7x.cfg
@@ -126,7 +126,7 @@ if { [info exists QUADSPI] && $QUADSPI } {
}
# Clock after reset is HSI at 64 MHz, no need of PLL
-adapter speed 1800
+adapter speed 4000
adapter srst delay 100
if {[using_jtag]} {
@@ -198,11 +198,6 @@ $_CHIPNAME.cpu0 configure -event examine-end {
stm32h7x_dbgmcu_mmw 0x3000 0x00000003 0
}
-$_CHIPNAME.cpu0 configure -event reset-init {
- # Clock after reset is HSI at 64 MHz, no need of PLL
- adapter speed 4000
-}
-
# get _CHIPNAME from current target
proc stm32h7x_get_chipname {} {
set t [target current]
-----------------------------------------------------------------------
Summary of changes:
tcl/target/stm32h7x.cfg | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-06 08:10:59
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 03b79387cce39fc2b88874f547dd3f9633b0b31b (commit)
from b8dc15f43b03298949bf529d76ee6c2356aee2fb (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 03b79387cce39fc2b88874f547dd3f9633b0b31b
Author: HAOUES Ahmed <ahm...@st...>
Date: Wed Jul 23 14:57:11 2025 +0100
flash/stm32h7x: support STM32H7R/H7Sx
The STM32H7R/H7Sx has a flash size up to 64 Kb
Change-Id: I2e9d80758d1bc88defdd6bbd1787026373b39fa4
Signed-off-by: HAOUES Ahmed <ahm...@st...>
Reviewed-on: https://review.openocd.org/c/openocd/+/8890
Reviewed-by: Tomas Vanek <va...@fb...>
Tested-by: jenkins
diff --git a/contrib/loaders/flash/stm32/stm32h7rx.S b/contrib/loaders/flash/stm32/stm32h7rx.S
new file mode 100644
index 000000000..bfc4929d0
--- /dev/null
+++ b/contrib/loaders/flash/stm32/stm32h7rx.S
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/***************************************************************************
+ * Copyright (C) 2017 by STMicroelectronics *
+ ***************************************************************************/
+
+ .text
+ .syntax unified
+ .cpu cortex-m4
+ .thumb
+
+/*
+ * 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 rp, wp and data, thus the minimum
+ * 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 (of write words)
+ * r4 = size of write word
+ * r5 = flash reg base
+ *
+ * Clobbered:
+ * r6 - rp
+ * r7 - wp, status, tmp
+ * r8 - loop index, tmp
+ */
+
+#define STM32_FLASH_CR_OFFSET 0x10 /* offset of CR register in FLASH struct */
+#define STM32_FLASH_SR_OFFSET 0x14 /* offset of SR register in FLASH struct */
+#define STM32_FLASH_ICR_OFFSET 0x28 /* offset of SR register in FLASH struct */
+#define STM32_CR_PROG 0x00000002 /* PG */
+#define STM32_SR_QW_MASK 0x00000004 /* QW */
+#define STM32_SR_ERROR_MASK 0x1F2E0000 /* DBECCERR | SNECCERR | RDSERR | RDPERR | OPERR
+ | INCERR | STRBERR | PGSERR | WRPERR */
+
+ .thumb_func
+ .global _start
+_start:
+ ldr r6, [r0, #4] /* read rp */
+
+wait_fifo:
+ 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 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 r7, #STM32_CR_PROG
+ str r7, [r5, #STM32_FLASH_CR_OFFSET]
+
+ mov r8, #4
+ udiv r8, r4, r8 /* number of words is size of write word divided by 4*/
+write_flash:
+ dsb
+ ldr r7, [r6], #0x04 /* read one word from src, increment ptr */
+ str r7, [r2], #0x04 /* write one word to dst, increment ptr */
+ dsb
+ cmp r6, r1 /* if rp >= end of buffer ... */
+ it cs
+ 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 r7, [r5, #STM32_FLASH_SR_OFFSET]
+ tst r7, #STM32_SR_QW_MASK
+ bne busy /* operation in progress, wait ... */
+
+ ldr r7, [r5, #STM32_FLASH_ICR_OFFSET]
+ ldr r8, =STM32_SR_ERROR_MASK
+ tst r7, r8
+ bne error /* fail... */
+
+ str r6, [r0, #4] /* store rp */
+ subs r3, r3, #1 /* decrement count */
+ bne wait_fifo /* loop if not done */
+ b exit
+
+error:
+ movs r8, #0
+ str r8, [r0, #4] /* set rp = 0 on error */
+
+exit:
+ mov r0, r7 /* return status in r0 */
+ bkpt #0x00
+
+ .pool
diff --git a/contrib/loaders/flash/stm32/stm32h7rx.inc b/contrib/loaders/flash/stm32/stm32h7rx.inc
new file mode 100644
index 000000000..feecab623
--- /dev/null
+++ b/contrib/loaders/flash/stm32/stm32h7rx.inc
@@ -0,0 +1,8 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0x46,0x68,0x07,0x68,0x77,0xb3,0xbf,0x1b,0x42,0xbf,0x7f,0x18,0x3f,0x1a,0x08,0x3f,
+0xa7,0x42,0xf6,0xd3,0x4f,0xf0,0x02,0x07,0x2f,0x61,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,
+0x6f,0x69,0x17,0xf0,0x04,0x0f,0xfb,0xd1,0xaf,0x6a,0xdf,0xf8,0x1c,0x80,0x17,0xea,
+0x08,0x0f,0x03,0xd1,0x46,0x60,0x01,0x3b,0xd3,0xd1,0x03,0xe0,0x5f,0xf0,0x00,0x08,
+0xc0,0xf8,0x04,0x80,0x38,0x46,0x00,0xbe,0x00,0x00,0x2e,0x1f,
diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c
index 4c4025b7e..e9096a54e 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -18,14 +18,21 @@
#define FLASH_WRITE_TIMEOUT 5
#define MASS_ERASE_TIMEOUT 30000
+static const uint8_t stm32h7_flash_write_code[] = {
+#include "../../../contrib/loaders/flash/stm32/stm32h7x.inc"
+};
+
+static const uint8_t stm32h7rs_flash_write_code[] = {
+#include "../../../contrib/loaders/flash/stm32/stm32h7rx.inc"
+};
+
enum stm32h7_flash_reg_index {
STM32_FLASH_ACR_INDEX,
STM32_FLASH_KEYR_INDEX,
STM32_FLASH_OPTKEYR_INDEX,
STM32_FLASH_SR_INDEX,
STM32_FLASH_CR_INDEX,
- STM32_FLASH_ICR_INDEX,
- STM32_FLASH_CCR_INDEX,
+ STM32_FLASH_ICR_CCR_INDEX,
STM32_FLASH_OPTCR_INDEX,
STM32_FLASH_OPTSR_INDEX,
STM32_FLASH_OPTSR_CUR_INDEX,
@@ -46,7 +53,7 @@ static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
[STM32_FLASH_OPTKEYR_INDEX] = 0x08,
[STM32_FLASH_SR_INDEX] = 0x10,
[STM32_FLASH_CR_INDEX] = 0x0C,
- [STM32_FLASH_CCR_INDEX] = 0x14,
+ [STM32_FLASH_ICR_CCR_INDEX] = 0x14,
[STM32_FLASH_OPTCR_INDEX] = 0x18,
[STM32_FLASH_OPTSR_CUR_INDEX] = 0x1C,
[STM32_FLASH_OPTSR_PRG_INDEX] = 0x20,
@@ -55,6 +62,18 @@ static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
[STM32_FLASH_WPSN_PRG_INDEX] = 0x3C
};
+static const uint32_t stm32h7rs_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
+ [STM32_FLASH_ACR_INDEX] = 0x00,
+ [STM32_FLASH_KEYR_INDEX] = 0x04,
+ [STM32_FLASH_OPTKEYR_INDEX] = 0x100,
+ [STM32_FLASH_SR_INDEX] = 0x14,
+ [STM32_FLASH_CR_INDEX] = 0x10,
+ [STM32_FLASH_ICR_CCR_INDEX] = 0x28,
+ [STM32_FLASH_OPTCR_INDEX] = 0x104,
+ [STM32_FLASH_OPTSR_INDEX] = 0x10C,
+ [STM32_FLASH_ISR_INDEX] = 0x24,
+};
+
/* FLASH_CR register bits */
#define FLASH_LOCK BIT(0)
#define FLASH_PG BIT(1)
@@ -67,6 +86,19 @@ static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
#define FLASH_FW BIT(6)
#define FLASH_START BIT(7)
+/* FLASH_ISR register bits for H7RS */
+#define FLASH_CRCRDERRF BIT(28) /* CRC read error flag */
+#define FLASH_CRCENDF BIT(27) /* CRC end flag */
+#define FLASH_DBECCERRF BIT(26) /* ECC double error flag */
+#define FLASH_SNECCERRF BIT(25) /* ECC single error flag */
+#define FLASH_RDSERRF BIT(24) /* Read security error flag */
+#define FLASH_INCERRF BIT(21) /* Inconsistency error flag */
+#define FLASH_OBLERRF BIT(20) /* Option byte loading error flag */
+#define FLASH_STRBERRF BIT(19) /* Strobe error flag */
+#define FLASH_PGSERRF BIT(18) /* Programming sequence error flag */
+#define FLASH_WRPERRF BIT(17) /* Write protection error flag */
+#define FLASH_EOPF BIT(16) /* End-of-program flag */
+
/* FLASH_SR register bits */
#define FLASH_BSY BIT(0) /* Operation in progress */
#define FLASH_QW BIT(2) /* Operation queue in progress */
@@ -82,6 +114,9 @@ static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
#define FLASH_ERROR (FLASH_WRPERR | FLASH_PGSERR | FLASH_STRBERR | FLASH_INCERR | FLASH_OPERR | \
FLASH_RDPERR | FLASH_RDSERR | FLASH_SNECCERR | FLASH_DBECCERR)
+/* Possible errors for H7RS */
+#define FLASH_ERROR_H7RS (FLASH_CRCRDERRF | FLASH_CRCENDF | FLASH_DBECCERRF | FLASH_SNECCERRF | FLASH_RDSERRF | \
+ FLASH_INCERRF | FLASH_OBLERRF | FLASH_STRBERRF | FLASH_PGSERRF | FLASH_WRPERRF | FLASH_EOPF)
/* FLASH_OPTCR register bits */
#define OPT_LOCK BIT(0)
@@ -114,6 +149,7 @@ static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
#define DEVID_STM32H74_H75XX 0x450
#define DEVID_STM32H7A_H7BXX 0x480
#define DEVID_STM32H72_H73XX 0x483
+#define DEVID_STM32H7R_H7SXX 0x485
struct stm32h7_rev {
uint16_t rev;
@@ -139,6 +175,9 @@ struct stm32h7_part_info {
/* function to compute flash_cr register values */
uint32_t (*compute_flash_cr)(uint32_t cmd, int snb);
int (*get_flash_error_status)(struct flash_bank *bank, uint32_t *status);
+ uint32_t flash_error;
+ const uint8_t *write_code;
+ size_t write_code_size;
};
struct stm32h7_flash_bank {
@@ -168,12 +207,16 @@ static const struct stm32h7_rev stm32h72_h73xx_revs[] = {
{ 0x1000, "A" }, { 0x1001, "Z" },
};
+static const struct stm32h7_rev stm32h7r_h7sxx_revs[] = {
+ { 0x1000, "A" }, { 0x2000, "B" },
+};
+
static uint32_t stm32h74_h75xx_compute_flash_cr(uint32_t cmd, int snb)
{
return cmd | (snb << 8);
}
-static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t cmd, int snb)
+static uint32_t stm32h7a_h7b_h7r_h7sxx_compute_flash_cr(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);
@@ -185,6 +228,7 @@ static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t cmd, int snb)
}
static int stm32h7_get_flash_status(struct flash_bank *bank, uint32_t *status);
+static int stm32h7rs_get_flash_status(struct flash_bank *bank, uint32_t *status);
static const struct stm32h7_part_info stm32h7_parts[] = {
{
@@ -202,6 +246,9 @@ static const struct stm32h7_part_info stm32h7_parts[] = {
.wps_mask = 0xFF,
.compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
.get_flash_error_status = stm32h7_get_flash_status,
+ .flash_error = FLASH_ERROR,
+ .write_code = stm32h7_flash_write_code,
+ .write_code_size = sizeof(stm32h7_flash_write_code),
},
{
.id = DEVID_STM32H7A_H7BXX,
@@ -216,8 +263,11 @@ static const struct stm32h7_part_info stm32h7_parts[] = {
.fsize_addr = 0x08FFF80C,
.wps_group_size = 4,
.wps_mask = 0xFFFFFFFF,
- .compute_flash_cr = stm32h7a_h7bxx_compute_flash_cr,
+ .compute_flash_cr = stm32h7a_h7b_h7r_h7sxx_compute_flash_cr,
.get_flash_error_status = stm32h7_get_flash_status,
+ .flash_error = FLASH_ERROR,
+ .write_code = stm32h7_flash_write_code,
+ .write_code_size = sizeof(stm32h7_flash_write_code),
},
{
.id = DEVID_STM32H72_H73XX,
@@ -234,6 +284,28 @@ static const struct stm32h7_part_info stm32h7_parts[] = {
.wps_mask = 0xFF,
.compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
.get_flash_error_status = stm32h7_get_flash_status,
+ .flash_error = FLASH_ERROR,
+ .write_code = stm32h7_flash_write_code,
+ .write_code_size = sizeof(stm32h7_flash_write_code),
+ },
+ {
+ .id = DEVID_STM32H7R_H7SXX,
+ .revs = stm32h7r_h7sxx_revs,
+ .num_revs = ARRAY_SIZE(stm32h7r_h7sxx_revs),
+ .device_str = "STM32H7Rx/7Sx",
+ .page_size_kb = 8,
+ .block_size = 16,
+ .max_flash_size_kb = 64,
+ .max_bank_size_kb = 64,
+ .has_dual_bank = false,
+ .fsize_addr = 0x08FFF80C,
+ .wps_group_size = 1,
+ .wps_mask = 0xFF,
+ .compute_flash_cr = stm32h7a_h7b_h7r_h7sxx_compute_flash_cr,
+ .get_flash_error_status = stm32h7rs_get_flash_status,
+ .flash_error = FLASH_ERROR_H7RS,
+ .write_code = stm32h7rs_flash_write_code,
+ .write_code_size = sizeof(stm32h7rs_flash_write_code),
},
};
@@ -302,10 +374,16 @@ static int stm32h7_get_flash_status(struct flash_bank *bank, uint32_t *status)
return stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, status);
}
+static int stm32h7rs_get_flash_status(struct flash_bank *bank, uint32_t *status)
+{
+ return stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_ISR_INDEX, status);
+}
+
static int stm32h7_wait_flash_op_queue(struct flash_bank *bank, int timeout)
{
uint32_t status;
int retval;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
/* wait for flash operations completion */
for (;;) {
@@ -324,16 +402,16 @@ static int stm32h7_wait_flash_op_queue(struct flash_bank *bank, int timeout)
}
if (status & FLASH_WRPERR) {
- LOG_ERROR("wait_flash_op_queue, WRPERR detected");
+ LOG_ERROR("wait_flash_op_queue, write protection error");
retval = ERROR_FAIL;
}
/* Clear error + EOP flags but report errors */
- if (status & FLASH_ERROR) {
+ if (status & stm32h7_info->part_info->flash_error) {
if (retval == ERROR_OK)
retval = ERROR_FAIL;
/* If this operation fails, we ignore it and report the original retval */
- stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, status);
+ stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_ICR_CCR_INDEX, status);
}
return retval;
}
@@ -611,24 +689,21 @@ static int stm32h7_write_block(struct flash_bank *bank, const uint8_t *buffer,
struct armv7m_algorithm armv7m_info;
int retval = ERROR_OK;
- static const uint8_t stm32h7_flash_write_code[] = {
-#include "../../../contrib/loaders/flash/stm32/stm32h7x.inc"
- };
-
- if (target_alloc_working_area(target, sizeof(stm32h7_flash_write_code),
+ if (target_alloc_working_area(target, stm32h7_info->part_info->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(stm32h7_flash_write_code),
- stm32h7_flash_write_code);
+ stm32h7_info->part_info->write_code_size,
+ stm32h7_info->part_info->write_code);
if (retval != ERROR_OK) {
target_free_working_area(target, write_algorithm);
return retval;
}
+
/* memory buffer */
while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
data_size /= 2;
@@ -680,10 +755,10 @@ static int stm32h7_write_block(struct flash_bank *bank, const uint8_t *buffer,
if (flash_sr & FLASH_WRPERR)
LOG_ERROR("flash memory write protected");
- if ((flash_sr & FLASH_ERROR) != 0) {
- LOG_ERROR("flash write failed, FLASH_SR = 0x%08" PRIx32, flash_sr);
+ if ((flash_sr & stm32h7_info->part_info->flash_error) != 0) {
+ LOG_ERROR("flash write failed, status = 0x%08" PRIx32, flash_sr);
/* Clear error + EOP flags but report errors */
- stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, flash_sr);
+ stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_ICR_CCR_INDEX, flash_sr);
retval = ERROR_FAIL;
}
}
@@ -810,8 +885,11 @@ static int stm32h7_probe(struct flash_bank *bank)
LOG_DEBUG("device id = 0x%08" PRIx32, stm32h7_info->idcode);
device_id = stm32h7_info->idcode & 0xfff;
-
- stm32h7_info->flash_regs = stm32h7_flash_regs;
+ if (device_id == DEVID_STM32H7R_H7SXX) {
+ stm32h7_info->flash_regs = stm32h7rs_flash_regs;
+ } else {
+ stm32h7_info->flash_regs = stm32h7_flash_regs;
+ }
for (unsigned int n = 0; n < ARRAY_SIZE(stm32h7_parts); n++) {
if (device_id == stm32h7_parts[n].id)
@@ -872,6 +950,7 @@ static int stm32h7_probe(struct flash_bank *bank)
flash_size_in_kb /= 2;
break;
case DEVID_STM32H72_H73XX:
+ case DEVID_STM32H7R_H7SXX:
break;
default:
LOG_ERROR("unsupported device");
diff --git a/tcl/target/stm32h7rsx.cfg b/tcl/target/stm32h7rsx.cfg
new file mode 100644
index 000000000..a51982bb2
--- /dev/null
+++ b/tcl/target/stm32h7rsx.cfg
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# script for stm32h7rsx family
+
+#
+# stm32h7rs 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 stm32h7rsx
+}
+
+# Issue an error when hla is used
+if { [using_hla] } {
+ echo "Error : hla does not support STM32H7RS devices"
+}
+
+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
+ } {
+ 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
+}
+
+target create $_CHIPNAME.ap0 mem_ap -dap $_CHIPNAME.dap -ap-num 0
+target create $_CHIPNAME.cpu0 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 1
+# test ram area
+$_CHIPNAME.cpu0 configure -work-area-phys 0x24000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+flash bank $_CHIPNAME.flash stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu0
+
+# Make sure that cpu0 is selected
+targets $_CHIPNAME.cpu0
+
+# Clock after reset is HSI at 64 MHz, no need of PLL
+adapter speed 4000
+
+adapter srst delay 100
+if {[using_jtag]} {
+ jtag_ntrst_delay 100
+}
+
+# use hardware reset
+#
+# The STM32H7RS does not support connect_assert_srst mode because the AXI is
+# unavailable while SRST is asserted, and that is used to access the DBGMCU
+# component at 0x5C001000 in the examine-end event handler.
+#
+reset_config srst_gates_jtag
+
+if {![using_hla]} {
+ # if srst is not fitted use SYSRESETREQ to
+ # perform a soft reset
+ $_CHIPNAME.cpu0 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
+ # makes the data access cacheable. This allows reading and writing data in the
+ # CPU cache from the debugger, which is far more useful than going straight to
+ # RAM when operating on typical variables, and is generally no worse when
+ # operating on special memory locations.
+ $_CHIPNAME.dap apcsw 0x08000000 0x08000000
+}
+
+$_CHIPNAME.cpu0 configure -event examine-end {
+ # Enable debug during low power modes (uses more power)
+ # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP
+ mmw 0x5C001004 0x00000007 0
+
+ # Enable clock for tracing
+ # DBGMCU_CR |= TRACECLKEN
+ mmw 0x5C001004 0x00100000 0
+}
-----------------------------------------------------------------------
Summary of changes:
.../flash/stm32/{stm32h7x.S => stm32h7rx.S} | 8 +-
contrib/loaders/flash/stm32/stm32h7rx.inc | 8 ++
src/flash/nor/stm32h7x.c | 119 +++++++++++++++++----
tcl/target/stm32h7rsx.cfg | 98 +++++++++++++++++
4 files changed, 210 insertions(+), 23 deletions(-)
copy contrib/loaders/flash/stm32/{stm32h7x.S => stm32h7rx.S} (90%)
create mode 100644 contrib/loaders/flash/stm32/stm32h7rx.inc
create mode 100644 tcl/target/stm32h7rsx.cfg
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-06 08:10:09
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via b8dc15f43b03298949bf529d76ee6c2356aee2fb (commit)
from fe3c626b3f2b3c4021d1cb50022dc0b848d39ac4 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit b8dc15f43b03298949bf529d76ee6c2356aee2fb
Author: HAOUES Ahmed <ahm...@st...>
Date: Thu Jul 3 17:38:20 2025 +0100
flash/stm32h7x: use BIT macro whenever possible
Use the BIT() macro in place of bare shifts
Change-Id: Iad66e12354fc3c76c718a793eb6689258d497b00
Signed-off-by: HAOUES Ahmed <ahm...@st...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9012
Tested-by: jenkins
Reviewed-by: Tomas Vanek <va...@fb...>
diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c
index a3030708f..4c4025b7e 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -9,6 +9,7 @@
#include "imp.h"
#include <helper/binarybuffer.h>
+#include <helper/bits.h>
#include <target/algorithm.h>
#include <target/cortex_m.h>
@@ -55,45 +56,45 @@ static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
};
/* FLASH_CR register bits */
-#define FLASH_LOCK (1 << 0)
-#define FLASH_PG (1 << 1)
-#define FLASH_SER (1 << 2)
-#define FLASH_BER (1 << 3)
+#define FLASH_LOCK BIT(0)
+#define FLASH_PG BIT(1)
+#define FLASH_SER BIT(2)
+#define FLASH_BER BIT(3)
#define FLASH_PSIZE_8 (0 << 4)
#define FLASH_PSIZE_16 (1 << 4)
#define FLASH_PSIZE_32 (2 << 4)
#define FLASH_PSIZE_64 (3 << 4)
-#define FLASH_FW (1 << 6)
-#define FLASH_START (1 << 7)
+#define FLASH_FW BIT(6)
+#define FLASH_START BIT(7)
/* FLASH_SR register bits */
-#define FLASH_BSY (1 << 0) /* Operation in progress */
-#define FLASH_QW (1 << 2) /* Operation queue in progress */
-#define FLASH_WRPERR (1 << 17) /* Write protection error */
-#define FLASH_PGSERR (1 << 18) /* Programming sequence error */
-#define FLASH_STRBERR (1 << 19) /* Strobe error */
-#define FLASH_INCERR (1 << 21) /* Inconsistency error */
-#define FLASH_OPERR (1 << 22) /* Operation error */
-#define FLASH_RDPERR (1 << 23) /* Read Protection error */
-#define FLASH_RDSERR (1 << 24) /* Secure Protection error */
-#define FLASH_SNECCERR (1 << 25) /* Single ECC error */
-#define FLASH_DBECCERR (1 << 26) /* Double ECC error */
+#define FLASH_BSY BIT(0) /* Operation in progress */
+#define FLASH_QW BIT(2) /* Operation queue in progress */
+#define FLASH_WRPERR BIT(17) /* Write protection error */
+#define FLASH_PGSERR BIT(18) /* Programming sequence error */
+#define FLASH_STRBERR BIT(19) /* Strobe error */
+#define FLASH_INCERR BIT(21) /* Inconsistency error */
+#define FLASH_OPERR BIT(22) /* Operation error */
+#define FLASH_RDPERR BIT(23) /* Read Protection error */
+#define FLASH_RDSERR BIT(24) /* Secure Protection error */
+#define FLASH_SNECCERR BIT(25) /* Single ECC error */
+#define FLASH_DBECCERR BIT(26) /* Double ECC error */
#define FLASH_ERROR (FLASH_WRPERR | FLASH_PGSERR | FLASH_STRBERR | FLASH_INCERR | FLASH_OPERR | \
FLASH_RDPERR | FLASH_RDSERR | FLASH_SNECCERR | FLASH_DBECCERR)
/* FLASH_OPTCR register bits */
-#define OPT_LOCK (1 << 0)
-#define OPT_START (1 << 1)
+#define OPT_LOCK BIT(0)
+#define OPT_START BIT(1)
/* FLASH_OPTSR register bits */
-#define OPT_BSY (1 << 0)
+#define OPT_BSY BIT(0)
#define OPT_RDP_POS 8
#define OPT_RDP_MASK (0xff << OPT_RDP_POS)
-#define OPT_OPTCHANGEERR (1 << 30)
+#define OPT_OPTCHANGEERR BIT(30)
/* FLASH_OPTCCR register bits */
-#define OPT_CLR_OPTCHANGEERR (1 << 30)
+#define OPT_CLR_OPTCHANGEERR BIT(30)
/* register unlock keys */
#define KEY1 0x45670123
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/stm32h7x.c | 45 +++++++++++++++++++++++----------------------
1 file changed, 23 insertions(+), 22 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-06 08:09:37
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via fe3c626b3f2b3c4021d1cb50022dc0b848d39ac4 (commit)
from e4e0faeba66799f0366b8c89992a7652db884d1a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit fe3c626b3f2b3c4021d1cb50022dc0b848d39ac4
Author: HAOUES Ahmed <ahm...@st...>
Date: Tue Jul 1 13:54:12 2025 +0100
flash/stm32h7x: Rename functions and variable names
Prepare support for STM32H7R/S
Rename methods to follow the STM32l4 driver naming
Change-Id: Iad14ba89a48a63c158dae05a53dcbf92f6fe2f53
Signed-off-by: HAOUES Ahmed <ahm...@st...>
Reviewed-on: https://review.openocd.org/c/openocd/+/8889
Tested-by: jenkins
Reviewed-by: Tomas Vanek <va...@fb...>
diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c
index da674725d..a3030708f 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -114,18 +114,18 @@ static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
#define DEVID_STM32H7A_H7BXX 0x480
#define DEVID_STM32H72_H73XX 0x483
-struct stm32h7x_rev {
+struct stm32h7_rev {
uint16_t rev;
const char *str;
};
-/* stm32h7x_part_info permits the store each device information and specificities.
+/* stm32h7_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 {
+struct stm32h7_part_info {
uint16_t id;
const char *device_str;
- const struct stm32h7x_rev *revs;
+ const struct stm32h7_rev *revs;
size_t num_revs;
unsigned int page_size_kb;
unsigned int block_size; /* flash write word size in bytes */
@@ -140,30 +140,30 @@ struct stm32h7x_part_info {
int (*get_flash_error_status)(struct flash_bank *bank, uint32_t *status);
};
-struct stm32h7x_flash_bank {
+struct stm32h7_flash_bank {
bool probed;
uint32_t idcode;
uint32_t user_bank_size;
uint32_t flash_regs_base; /* Address of flash reg controller */
const uint32_t *flash_regs;
- const struct stm32h7x_part_info *part_info;
+ const struct stm32h7_part_info *part_info;
};
-enum stm32h7x_opt_rdp {
+enum stm32h7_opt_rdp {
OPT_RDP_L0 = 0xaa,
OPT_RDP_L1 = 0x00,
OPT_RDP_L2 = 0xcc
};
-static const struct stm32h7x_rev stm32h74_h75xx_revs[] = {
+static const struct stm32h7_rev stm32h74_h75xx_revs[] = {
{ 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X" }, { 0x2003, "V" },
};
-static const struct stm32h7x_rev stm32h7a_h7bxx_revs[] = {
+static const struct stm32h7_rev stm32h7a_h7bxx_revs[] = {
{ 0x1000, "A"},
};
-static const struct stm32h7x_rev stm32h72_h73xx_revs[] = {
+static const struct stm32h7_rev stm32h72_h73xx_revs[] = {
{ 0x1000, "A" }, { 0x1001, "Z" },
};
@@ -183,9 +183,9 @@ static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t cmd, int snb)
return cmd | (tmp >> 2) | (snb << 6);
}
-static int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status);
+static int stm32h7_get_flash_status(struct flash_bank *bank, uint32_t *status);
-static const struct stm32h7x_part_info stm32h7x_parts[] = {
+static const struct stm32h7_part_info stm32h7_parts[] = {
{
.id = DEVID_STM32H74_H75XX,
.revs = stm32h74_h75xx_revs,
@@ -200,7 +200,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
.wps_group_size = 1,
.wps_mask = 0xFF,
.compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
- .get_flash_error_status = stm32x_get_flash_status,
+ .get_flash_error_status = stm32h7_get_flash_status,
},
{
.id = DEVID_STM32H7A_H7BXX,
@@ -216,7 +216,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
.wps_group_size = 4,
.wps_mask = 0xFFFFFFFF,
.compute_flash_cr = stm32h7a_h7bxx_compute_flash_cr,
- .get_flash_error_status = stm32x_get_flash_status,
+ .get_flash_error_status = stm32h7_get_flash_status,
},
{
.id = DEVID_STM32H72_H73XX,
@@ -232,37 +232,37 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
.wps_group_size = 1,
.wps_mask = 0xFF,
.compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
- .get_flash_error_status = stm32x_get_flash_status,
+ .get_flash_error_status = stm32h7_get_flash_status,
},
};
/* flash bank stm32x <base> <size> 0 0 <target#> */
-FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)
+FLASH_BANK_COMMAND_HANDLER(stm32h7_flash_bank_command)
{
- struct stm32h7x_flash_bank *stm32x_info;
+ struct stm32h7_flash_bank *stm32h7_info;
if (CMD_ARGC < 6)
return ERROR_COMMAND_SYNTAX_ERROR;
- stm32x_info = malloc(sizeof(struct stm32h7x_flash_bank));
- bank->driver_priv = stm32x_info;
+ stm32h7_info = malloc(sizeof(struct stm32h7_flash_bank));
+ bank->driver_priv = stm32h7_info;
- stm32x_info->probed = false;
- stm32x_info->user_bank_size = bank->size;
+ stm32h7_info->probed = false;
+ stm32h7_info->user_bank_size = bank->size;
return ERROR_OK;
}
-static inline uint32_t stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset)
+static inline uint32_t stm32h7_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_regs_base;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
+ return reg_offset + stm32h7_info->flash_regs_base;
}
-static int stm32x_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value)
+static int stm32h7_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value)
{
- uint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset);
+ uint32_t reg_addr = stm32h7_get_flash_reg(bank, reg_offset);
int retval = target_read_u32(bank->target, reg_addr, value);
if (retval != ERROR_OK)
@@ -271,16 +271,16 @@ static int stm32x_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, u
return retval;
}
-static inline int stm32x_read_flash_reg_by_index(struct flash_bank *bank,
+static inline int stm32h7_read_flash_reg_by_index(struct flash_bank *bank,
enum stm32h7_flash_reg_index reg_index, uint32_t *value)
{
- struct stm32h7x_flash_bank *stm32h7_info = bank->driver_priv;
- return stm32x_read_flash_reg(bank, stm32h7_info->flash_regs[reg_index], value);
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
+ return stm32h7_read_flash_reg(bank, stm32h7_info->flash_regs[reg_index], value);
}
-static int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
+static int stm32h7_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
{
- uint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset);
+ uint32_t reg_addr = stm32h7_get_flash_reg(bank, reg_offset);
int retval = target_write_u32(bank->target, reg_addr, value);
if (retval != ERROR_OK)
@@ -289,26 +289,26 @@ static int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset,
return retval;
}
-static inline int stm32x_write_flash_reg_by_index(struct flash_bank *bank,
+static inline int stm32h7_write_flash_reg_by_index(struct flash_bank *bank,
enum stm32h7_flash_reg_index reg_index, uint32_t value)
{
- struct stm32h7x_flash_bank *stm32h7_info = bank->driver_priv;
- return stm32x_write_flash_reg(bank, stm32h7_info->flash_regs[reg_index], value);
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
+ return stm32h7_write_flash_reg(bank, stm32h7_info->flash_regs[reg_index], value);
}
-static int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)
+static int stm32h7_get_flash_status(struct flash_bank *bank, uint32_t *status)
{
- return stm32x_read_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, status);
+ return stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, status);
}
-static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout)
+static int stm32h7_wait_flash_op_queue(struct flash_bank *bank, int timeout)
{
uint32_t status;
int retval;
/* wait for flash operations completion */
for (;;) {
- retval = stm32x_get_flash_status(bank, &status);
+ retval = stm32h7_get_flash_status(bank, &status);
if (retval != ERROR_OK)
return retval;
@@ -332,19 +332,19 @@ 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 */
- stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, status);
+ stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, status);
}
return retval;
}
-static int stm32x_unlock_reg(struct flash_bank *bank)
+static int stm32h7_unlock_reg(struct flash_bank *bank)
{
uint32_t ctrl;
/* first check if not already unlocked
* otherwise writing on FLASH_KEYR will fail
*/
- int retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, &ctrl);
+ int retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, &ctrl);
if (retval != ERROR_OK)
return retval;
@@ -352,15 +352,15 @@ static int stm32x_unlock_reg(struct flash_bank *bank)
return ERROR_OK;
/* unlock flash registers for bank */
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, KEY1);
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, KEY1);
if (retval != ERROR_OK)
return retval;
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, KEY2);
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, KEY2);
if (retval != ERROR_OK)
return retval;
- retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, &ctrl);
+ retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, &ctrl);
if (retval != ERROR_OK)
return retval;
@@ -371,11 +371,11 @@ static int stm32x_unlock_reg(struct flash_bank *bank)
return ERROR_OK;
}
-static int stm32x_unlock_option_reg(struct flash_bank *bank)
+static int stm32h7_unlock_option_reg(struct flash_bank *bank)
{
uint32_t ctrl;
- int retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, &ctrl);
+ int retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, &ctrl);
if (retval != ERROR_OK)
return retval;
@@ -383,15 +383,15 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank)
return ERROR_OK;
/* unlock option registers */
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTKEYR_INDEX, OPTKEY1);
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_OPTKEYR_INDEX, OPTKEY1);
if (retval != ERROR_OK)
return retval;
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTKEYR_INDEX, OPTKEY2);
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_OPTKEYR_INDEX, OPTKEY2);
if (retval != ERROR_OK)
return retval;
- retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, &ctrl);
+ retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, &ctrl);
if (retval != ERROR_OK)
return retval;
@@ -403,37 +403,37 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank)
return ERROR_OK;
}
-static inline int stm32x_lock_reg(struct flash_bank *bank)
+static inline int stm32h7_lock_reg(struct flash_bank *bank)
{
- return stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, FLASH_LOCK);
+ return stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, FLASH_LOCK);
}
-static inline int stm32x_lock_option_reg(struct flash_bank *bank)
+static inline int stm32h7_lock_option_reg(struct flash_bank *bank)
{
- return stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, OPT_LOCK);
+ return stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, OPT_LOCK);
}
-static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
+static int stm32h7_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
{
int retval, retval2;
/* unlock option bytes for modification */
- retval = stm32x_unlock_option_reg(bank);
+ retval = stm32h7_unlock_option_reg(bank);
if (retval != ERROR_OK)
goto flash_options_lock;
/* write option bytes */
- retval = stm32x_write_flash_reg_by_index(bank, reg_offset, value);
+ retval = stm32h7_write_flash_reg_by_index(bank, reg_offset, value);
if (retval != ERROR_OK)
goto flash_options_lock;
/* Remove OPT error flag before programming */
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTCCR_INDEX, OPT_CLR_OPTCHANGEERR);
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_OPTCCR_INDEX, OPT_CLR_OPTCHANGEERR);
if (retval != ERROR_OK)
goto flash_options_lock;
/* start programming cycle */
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, OPT_START);
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, OPT_START);
if (retval != ERROR_OK)
goto flash_options_lock;
@@ -441,9 +441,9 @@ static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uin
int timeout = FLASH_ERASE_TIMEOUT;
uint32_t status;
for (;;) {
- retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_OPTSR_CUR_INDEX, &status);
+ retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_OPTSR_CUR_INDEX, &status);
if (retval != ERROR_OK) {
- LOG_ERROR("stm32x_options_program: failed to read FLASH_OPTSR_CUR");
+ LOG_ERROR("stm32h7_options_program: failed to read FLASH_OPTSR_CUR");
goto flash_options_lock;
}
if ((status & OPT_BSY) == 0)
@@ -464,32 +464,32 @@ static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uin
}
flash_options_lock:
- retval2 = stm32x_lock_option_reg(bank);
+ retval2 = stm32h7_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)
+static int stm32h7_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_by_index(bank, reg_offset, &data);
+ int retval = stm32h7_read_flash_reg_by_index(bank, reg_offset, &data);
if (retval != ERROR_OK)
return retval;
data = (data & ~mask) | (value & mask);
- return stm32x_write_option(bank, reg_offset, data);
+ return stm32h7_write_option(bank, reg_offset, data);
}
-static int stm32x_protect_check(struct flash_bank *bank)
+static int stm32h7_protect_check(struct flash_bank *bank)
{
uint32_t protection;
/* read 'write protection' settings */
- int retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_WPSN_CUR_INDEX, &protection);
+ int retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_WPSN_CUR_INDEX, &protection);
if (retval != ERROR_OK) {
LOG_DEBUG("unable to read WPSN_CUR register");
return retval;
@@ -501,10 +501,10 @@ static int stm32x_protect_check(struct flash_bank *bank)
return ERROR_OK;
}
-static int stm32x_erase(struct flash_bank *bank, unsigned int first,
+static int stm32h7_erase(struct flash_bank *bank, unsigned int first,
unsigned int last)
{
- struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
int retval, retval2;
assert(first < bank->num_sectors);
@@ -513,7 +513,7 @@ static int stm32x_erase(struct flash_bank *bank, unsigned int first,
if (bank->target->state != TARGET_HALTED)
return ERROR_TARGET_NOT_HALTED;
- retval = stm32x_unlock_reg(bank);
+ retval = stm32h7_unlock_reg(bank);
if (retval != ERROR_OK)
goto flash_lock;
@@ -529,19 +529,19 @@ static int stm32x_erase(struct flash_bank *bank, unsigned int first,
*/
for (unsigned int i = first; i <= last; i++) {
LOG_DEBUG("erase sector %u", i);
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
- stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64, i));
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
+ stm32h7_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64, i));
if (retval != ERROR_OK) {
LOG_ERROR("Error erase sector %u", i);
goto flash_lock;
}
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
- stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64 | FLASH_START, i));
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
+ stm32h7_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64 | FLASH_START, i));
if (retval != ERROR_OK) {
LOG_ERROR("Error erase sector %u", i);
goto flash_lock;
}
- retval = stm32x_wait_flash_op_queue(bank, FLASH_ERASE_TIMEOUT);
+ retval = stm32h7_wait_flash_op_queue(bank, FLASH_ERASE_TIMEOUT);
if (retval != ERROR_OK) {
LOG_ERROR("erase time-out or operation error sector %u", i);
@@ -550,18 +550,18 @@ static int stm32x_erase(struct flash_bank *bank, unsigned int first,
}
flash_lock:
- retval2 = stm32x_lock_reg(bank);
+ retval2 = stm32h7_lock_reg(bank);
if (retval2 != ERROR_OK)
LOG_ERROR("error during the lock of flash");
return (retval == ERROR_OK) ? retval2 : retval;
}
-static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
+static int stm32h7_protect(struct flash_bank *bank, int set, unsigned int first,
unsigned int last)
{
struct target *target = bank->target;
- struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
uint32_t protection;
if (target->state != TARGET_HALTED) {
@@ -570,7 +570,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
}
/* read 'write protection' settings */
- int retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_WPSN_CUR_INDEX, &protection);
+ int retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_WPSN_CUR_INDEX, &protection);
if (retval != ERROR_OK) {
LOG_DEBUG("unable to read WPSN_CUR register");
return retval;
@@ -584,24 +584,24 @@ static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
}
/* apply WRPSN mask */
- protection &= stm32x_info->part_info->wps_mask;
+ protection &= stm32h7_info->part_info->wps_mask;
- LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%" PRIx32, protection);
+ LOG_DEBUG("stm32h7_protect, option_bytes written WPSN 0x%" PRIx32, protection);
/* apply new option value */
- return stm32x_write_option(bank, STM32_FLASH_WPSN_PRG_INDEX, protection);
+ return stm32h7_write_option(bank, STM32_FLASH_WPSN_PRG_INDEX, protection);
}
-static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
+static int stm32h7_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;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
/*
* 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 * stm32x_info->part_info->block_size;
+ uint32_t data_size = 512 * stm32h7_info->part_info->block_size;
uint32_t buffer_size = 8 + data_size;
struct working_area *write_algorithm;
struct working_area *source;
@@ -610,19 +610,19 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
struct armv7m_algorithm armv7m_info;
int retval = ERROR_OK;
- static const uint8_t stm32x_flash_write_code[] = {
+ static const uint8_t stm32h7_flash_write_code[] = {
#include "../../../contrib/loaders/flash/stm32/stm32h7x.inc"
};
- if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code),
+ if (target_alloc_working_area(target, sizeof(stm32h7_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;
}
retval = target_write_buffer(target, write_algorithm->address,
- sizeof(stm32x_flash_write_code),
- stm32x_flash_write_code);
+ sizeof(stm32h7_flash_write_code),
+ stm32h7_flash_write_code);
if (retval != ERROR_OK) {
target_free_working_area(target, write_algorithm);
return retval;
@@ -658,13 +658,13 @@ 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->part_info->block_size);
- buf_set_u32(reg_params[5].value, 0, 32, stm32x_info->flash_regs_base);
+ buf_set_u32(reg_params[4].value, 0, 32, stm32h7_info->part_info->block_size);
+ buf_set_u32(reg_params[5].value, 0, 32, stm32h7_info->flash_regs_base);
retval = target_run_flash_async_algorithm(target,
buffer,
count,
- stm32x_info->part_info->block_size,
+ stm32h7_info->part_info->block_size,
0, NULL,
ARRAY_SIZE(reg_params), reg_params,
source->address, source->size,
@@ -672,7 +672,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
&armv7m_info);
if (retval == ERROR_FLASH_OPERATION_FAILED) {
- LOG_ERROR("error executing stm32h7x flash write algorithm");
+ LOG_ERROR("error executing stm32h7 flash write algorithm");
uint32_t flash_sr = buf_get_u32(reg_params[0].value, 0, 32);
@@ -682,7 +682,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 = 0x%08" PRIx32, flash_sr);
/* Clear error + EOP flags but report errors */
- stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, flash_sr);
+ stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, flash_sr);
retval = ERROR_FAIL;
}
}
@@ -699,11 +699,11 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
return retval;
}
-static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,
+static int stm32h7_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;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
uint32_t address = bank->base + offset;
int retval, retval2;
@@ -713,20 +713,20 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,
}
/* should be enforced via bank->write_start_alignment */
- assert(!(offset % stm32x_info->part_info->block_size));
+ assert(!(offset % stm32h7_info->part_info->block_size));
/* should be enforced via bank->write_end_alignment */
- assert(!(count % stm32x_info->part_info->block_size));
+ assert(!(count % stm32h7_info->part_info->block_size));
- retval = stm32x_unlock_reg(bank);
+ retval = stm32h7_unlock_reg(bank);
if (retval != ERROR_OK)
goto flash_lock;
- uint32_t blocks_remaining = count / stm32x_info->part_info->block_size;
+ uint32_t blocks_remaining = count / stm32h7_info->part_info->block_size;
/* multiple words (n * .block_size) to be programmed in block */
if (blocks_remaining) {
- retval = stm32x_write_block(bank, buffer, offset, blocks_remaining);
+ retval = stm32h7_write_block(bank, buffer, offset, blocks_remaining);
if (retval != ERROR_OK) {
if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
/* if block write failed (no sufficient working area),
@@ -734,8 +734,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 * stm32x_info->part_info->block_size;
- address += blocks_remaining * stm32x_info->part_info->block_size;
+ buffer += blocks_remaining * stm32h7_info->part_info->block_size;
+ address += blocks_remaining * stm32h7_info->part_info->block_size;
blocks_remaining = 0;
}
if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))
@@ -752,33 +752,33 @@ 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_by_index(bank, STM32_FLASH_CR_INDEX,
- stm32x_info->part_info->compute_flash_cr(FLASH_PG | FLASH_PSIZE_64, 0));
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
+ stm32h7_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, stm32x_info->part_info->block_size, buffer);
+ retval = target_write_buffer(target, address, stm32h7_info->part_info->block_size, buffer);
if (retval != ERROR_OK)
goto flash_lock;
- retval = stm32x_wait_flash_op_queue(bank, FLASH_WRITE_TIMEOUT);
+ retval = stm32h7_wait_flash_op_queue(bank, FLASH_WRITE_TIMEOUT);
if (retval != ERROR_OK)
goto flash_lock;
- buffer += stm32x_info->part_info->block_size;
- address += stm32x_info->part_info->block_size;
+ buffer += stm32h7_info->part_info->block_size;
+ address += stm32h7_info->part_info->block_size;
blocks_remaining--;
}
flash_lock:
- retval2 = stm32x_lock_reg(bank);
+ retval2 = stm32h7_lock_reg(bank);
if (retval2 != ERROR_OK)
LOG_ERROR("error during the lock of flash");
return (retval == ERROR_OK) ? retval2 : retval;
}
-static int stm32x_read_id_code(struct flash_bank *bank, uint32_t *id)
+static int stm32h7_read_id_code(struct flash_bank *bank, uint32_t *id)
{
/* read stm32 device id register */
int retval = target_read_u32(bank->target, DBGMCU_IDCODE_REGISTER, id);
@@ -787,52 +787,52 @@ static int stm32x_read_id_code(struct flash_bank *bank, uint32_t *id)
return ERROR_OK;
}
-static int stm32x_probe(struct flash_bank *bank)
+static int stm32h7_probe(struct flash_bank *bank)
{
struct target *target = bank->target;
- struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
uint16_t flash_size_in_kb;
uint32_t device_id;
- stm32x_info->probed = false;
- stm32x_info->part_info = NULL;
+ stm32h7_info->probed = false;
+ stm32h7_info->part_info = NULL;
if (!target_was_examined(target)) {
LOG_ERROR("Target not examined yet");
return ERROR_TARGET_NOT_EXAMINED;
}
- int retval = stm32x_read_id_code(bank, &stm32x_info->idcode);
+ int retval = stm32h7_read_id_code(bank, &stm32h7_info->idcode);
if (retval != ERROR_OK)
return retval;
- LOG_DEBUG("device id = 0x%08" PRIx32, stm32x_info->idcode);
+ LOG_DEBUG("device id = 0x%08" PRIx32, stm32h7_info->idcode);
- device_id = stm32x_info->idcode & 0xfff;
+ device_id = stm32h7_info->idcode & 0xfff;
- stm32x_info->flash_regs = stm32h7_flash_regs;
+ stm32h7_info->flash_regs = stm32h7_flash_regs;
- for (unsigned int n = 0; n < ARRAY_SIZE(stm32h7x_parts); n++) {
- if (device_id == stm32h7x_parts[n].id)
- stm32x_info->part_info = &stm32h7x_parts[n];
+ for (unsigned int n = 0; n < ARRAY_SIZE(stm32h7_parts); n++) {
+ if (device_id == stm32h7_parts[n].id)
+ stm32h7_info->part_info = &stm32h7_parts[n];
}
- if (!stm32x_info->part_info) {
+ if (!stm32h7_info->part_info) {
LOG_WARNING("Cannot identify target as a STM32H7xx family.");
return ERROR_FAIL;
} else {
- LOG_INFO("Device: %s", stm32x_info->part_info->device_str);
+ LOG_INFO("Device: %s", stm32h7_info->part_info->device_str);
}
/* update the address of controller */
if (bank->base == FLASH_BANK0_ADDRESS)
- stm32x_info->flash_regs_base = FLASH_REG_BASE_B0;
+ stm32h7_info->flash_regs_base = FLASH_REG_BASE_B0;
else if (bank->base == FLASH_BANK1_ADDRESS)
- stm32x_info->flash_regs_base = FLASH_REG_BASE_B1;
+ stm32h7_info->flash_regs_base = FLASH_REG_BASE_B1;
else {
LOG_WARNING("Flash register base not defined for bank %u", bank->bank_number);
return ERROR_FAIL;
}
- LOG_DEBUG("flash_regs_base: 0x%" PRIx32, stm32x_info->flash_regs_base);
+ LOG_DEBUG("flash_regs_base: 0x%" PRIx32, stm32h7_info->flash_regs_base);
/* get flash size from target */
/* STM32H74x/H75x, the second core (Cortex-M4) cannot read the flash size */
@@ -841,19 +841,19 @@ static int stm32x_probe(struct flash_bank *bank)
&& cortex_m_get_impl_part(target) == CORTEX_M4_PARTNO)
LOG_WARNING("%s cannot read the flash size register", target_name(target));
else
- retval = target_read_u16(target, stm32x_info->part_info->fsize_addr, &flash_size_in_kb);
+ retval = target_read_u16(target, stm32h7_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;
+ flash_size_in_kb = stm32h7_info->part_info->max_flash_size_kb;
LOG_INFO("assuming %" PRIu16 "k flash", flash_size_in_kb);
} else
LOG_INFO("flash size probed value %" PRIu16 "k", flash_size_in_kb);
/* 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;
+ const uint32_t bank2_base = bank1_base + stm32h7_info->part_info->max_bank_size_kb * 1024;
+ bool has_dual_bank = stm32h7_info->part_info->has_dual_bank;
switch (device_id) {
case DEVID_STM32H74_H75XX:
@@ -903,27 +903,27 @@ static int stm32x_probe(struct flash_bank *bank)
/* 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) {
+ if (stm32h7_info->user_bank_size) {
LOG_INFO("ignoring flash probed value, using configured bank size");
- flash_size_in_kb = stm32x_info->user_bank_size / 1024;
+ flash_size_in_kb = stm32h7_info->user_bank_size / 1024;
} else if (flash_size_in_kb == 0xffff) {
/* die flash size */
- flash_size_in_kb = stm32x_info->part_info->max_flash_size_kb;
+ flash_size_in_kb = stm32h7_info->part_info->max_flash_size_kb;
}
/* did we assign flash size? */
assert(flash_size_in_kb != 0xffff);
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;
+ bank->write_start_alignment = stm32h7_info->part_info->block_size;
+ bank->write_end_alignment = stm32h7_info->part_info->block_size;
/* setup sectors */
- bank->num_sectors = flash_size_in_kb / stm32x_info->part_info->page_size_kb;
+ bank->num_sectors = flash_size_in_kb / stm32h7_info->part_info->page_size_kb;
assert(bank->num_sectors > 0);
free(bank->sectors);
- bank->sectors = alloc_block_array(0, stm32x_info->part_info->page_size_kb * 1024,
+ bank->sectors = alloc_block_array(0, stm32h7_info->part_info->page_size_kb * 1024,
bank->num_sectors);
if (!bank->sectors) {
@@ -932,7 +932,7 @@ static int stm32x_probe(struct flash_bank *bank)
}
/* setup protection blocks */
- const uint32_t wpsn = stm32x_info->part_info->wps_group_size;
+ const uint32_t wpsn = stm32h7_info->part_info->wps_group_size;
assert(bank->num_sectors % wpsn == 0);
bank->num_prot_blocks = bank->num_sectors / wpsn;
@@ -940,7 +940,7 @@ static int stm32x_probe(struct flash_bank *bank)
free(bank->prot_blocks);
- bank->prot_blocks = alloc_block_array(0, stm32x_info->part_info->page_size_kb * wpsn * 1024,
+ bank->prot_blocks = alloc_block_array(0, stm32h7_info->part_info->page_size_kb * wpsn * 1024,
bank->num_prot_blocks);
if (!bank->prot_blocks) {
@@ -948,28 +948,28 @@ static int stm32x_probe(struct flash_bank *bank)
return ERROR_FAIL;
}
- stm32x_info->probed = true;
+ stm32h7_info->probed = true;
return ERROR_OK;
}
-static int stm32x_auto_probe(struct flash_bank *bank)
+static int stm32h7_auto_probe(struct flash_bank *bank)
{
- struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
- if (stm32x_info->probed)
+ if (stm32h7_info->probed)
return ERROR_OK;
- return stm32x_probe(bank);
+ return stm32h7_probe(bank);
}
/* This method must return a string displaying information about the bank */
-static int stm32x_get_info(struct flash_bank *bank, struct command_invocation *cmd)
+static int stm32h7_get_info(struct flash_bank *bank, struct command_invocation *cmd)
{
- struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
- const struct stm32h7x_part_info *info = stm32x_info->part_info;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
+ const struct stm32h7_part_info *info = stm32h7_info->part_info;
- if (!stm32x_info->probed) {
- int retval = stm32x_probe(bank);
+ if (!stm32h7_info->probed) {
+ int retval = stm32h7_probe(bank);
if (retval != ERROR_OK) {
command_print_sameline(cmd, "Unable to find bank information.");
return retval;
@@ -978,7 +978,7 @@ static int stm32x_get_info(struct flash_bank *bank, struct command_invocation *c
if (info) {
const char *rev_str = NULL;
- uint16_t rev_id = stm32x_info->idcode >> 16;
+ uint16_t rev_id = stm32h7_info->idcode >> 16;
for (unsigned int i = 0; i < info->num_revs; i++)
if (rev_id == info->revs[i].rev)
@@ -986,11 +986,11 @@ static int stm32x_get_info(struct flash_bank *bank, struct command_invocation *c
if (rev_str) {
command_print_sameline(cmd, "%s - Rev: %s",
- stm32x_info->part_info->device_str, rev_str);
+ stm32h7_info->part_info->device_str, rev_str);
} else {
command_print_sameline(cmd,
"%s - Rev: unknown (0x%04" PRIx16 ")",
- stm32x_info->part_info->device_str, rev_id);
+ stm32h7_info->part_info->device_str, rev_id);
}
} else {
command_print_sameline(cmd, "Cannot identify target as a STM32H7x");
@@ -999,7 +999,7 @@ static int stm32x_get_info(struct flash_bank *bank, struct command_invocation *c
return ERROR_OK;
}
-static int stm32x_set_rdp(struct flash_bank *bank, enum stm32h7x_opt_rdp new_rdp)
+static int stm32h7_set_rdp(struct flash_bank *bank, enum stm32h7_opt_rdp new_rdp)
{
struct target *target = bank->target;
uint32_t optsr, cur_rdp;
@@ -1010,7 +1010,7 @@ static int stm32x_set_rdp(struct flash_bank *bank, enum stm32h7x_opt_rdp new_rdp
return ERROR_TARGET_NOT_HALTED;
}
- retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_OPTSR_PRG_INDEX, &optsr);
+ retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_OPTSR_PRG_INDEX, &optsr);
if (retval != ERROR_OK) {
LOG_DEBUG("unable to read FLASH_OPTSR_PRG register");
@@ -1040,10 +1040,10 @@ static int stm32x_set_rdp(struct flash_bank *bank, enum stm32h7x_opt_rdp new_rdp
optsr = (optsr & ~OPT_RDP_MASK) | (new_rdp << OPT_RDP_POS);
/* apply new option value */
- return stm32x_write_option(bank, STM32_FLASH_OPTSR_PRG_INDEX, optsr);
+ return stm32h7_write_option(bank, STM32_FLASH_OPTSR_PRG_INDEX, optsr);
}
-COMMAND_HANDLER(stm32x_handle_lock_command)
+COMMAND_HANDLER(stm32h7_handle_lock_command)
{
if (CMD_ARGC < 1)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1053,7 +1053,7 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
if (retval != ERROR_OK)
return retval;
- retval = stm32x_set_rdp(bank, OPT_RDP_L1);
+ retval = stm32h7_set_rdp(bank, OPT_RDP_L1);
if (retval != ERROR_OK)
command_print(CMD, "%s failed to lock device", bank->driver->name);
@@ -1063,7 +1063,7 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
return retval;
}
-COMMAND_HANDLER(stm32x_handle_unlock_command)
+COMMAND_HANDLER(stm32h7_handle_unlock_command)
{
if (CMD_ARGC < 1)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1073,7 +1073,7 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
if (retval != ERROR_OK)
return retval;
- retval = stm32x_set_rdp(bank, OPT_RDP_L0);
+ retval = stm32h7_set_rdp(bank, OPT_RDP_L0);
if (retval != ERROR_OK)
command_print(CMD, "%s failed to unlock device", bank->driver->name);
@@ -1083,45 +1083,45 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
return retval;
}
-static int stm32x_mass_erase(struct flash_bank *bank)
+static int stm32h7_mass_erase(struct flash_bank *bank)
{
int retval, retval2;
struct target *target = bank->target;
- struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
+ struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
}
- retval = stm32x_unlock_reg(bank);
+ retval = stm32h7_unlock_reg(bank);
if (retval != ERROR_OK)
goto flash_lock;
/* mass erase flash memory bank */
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
- stm32x_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64, 0));
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
+ stm32h7_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64, 0));
if (retval != ERROR_OK)
goto flash_lock;
- retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
- stm32x_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64 | FLASH_START, 0));
+ retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
+ stm32h7_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64 | FLASH_START, 0));
if (retval != ERROR_OK)
goto flash_lock;
- retval = stm32x_wait_flash_op_queue(bank, MASS_ERASE_TIMEOUT);
+ retval = stm32h7_wait_flash_op_queue(bank, MASS_ERASE_TIMEOUT);
if (retval != ERROR_OK)
goto flash_lock;
flash_lock:
- retval2 = stm32x_lock_reg(bank);
+ retval2 = stm32h7_lock_reg(bank);
if (retval2 != ERROR_OK)
LOG_ERROR("error during the lock of flash");
return (retval == ERROR_OK) ? retval2 : retval;
}
-COMMAND_HANDLER(stm32x_handle_mass_erase_command)
+COMMAND_HANDLER(stm32h7_handle_mass_erase_command)
{
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1131,7 +1131,7 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command)
if (retval != ERROR_OK)
return retval;
- retval = stm32x_mass_erase(bank);
+ retval = stm32h7_mass_erase(bank);
if (retval == ERROR_OK)
command_print(CMD, "stm32h7x mass erase complete");
else
@@ -1140,7 +1140,7 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command)
return retval;
}
-COMMAND_HANDLER(stm32x_handle_option_read_command)
+COMMAND_HANDLER(stm32h7_handle_option_read_command)
{
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1153,17 +1153,17 @@ COMMAND_HANDLER(stm32x_handle_option_read_command)
uint32_t reg_offset, value;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset);
- retval = stm32x_read_flash_reg_by_index(bank, reg_offset, &value);
+ retval = stm32h7_read_flash_reg_by_index(bank, reg_offset, &value);
if (retval != ERROR_OK)
return retval;
command_print(CMD, "Option Register: <0x%" PRIx32 "> = 0x%" PRIx32,
- stm32x_get_flash_reg(bank, reg_offset), value);
+ stm32h7_get_flash_reg(bank, reg_offset), value);
return retval;
}
-COMMAND_HANDLER(stm32x_handle_option_write_command)
+COMMAND_HANDLER(stm32h7_handle_option_write_command)
{
if (CMD_ARGC != 3 && CMD_ARGC != 4)
return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1180,41 +1180,41 @@ COMMAND_HANDLER(stm32x_handle_option_write_command)
if (CMD_ARGC > 3)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], mask);
- return stm32x_modify_option(bank, reg_offset, value, mask);
+ return stm32h7_modify_option(bank, reg_offset, value, mask);
}
-static const struct command_registration stm32h7x_exec_command_handlers[] = {
+static const struct command_registration stm32h7_exec_command_handlers[] = {
{
.name = "lock",
- .handler = stm32x_handle_lock_command,
+ .handler = stm32h7_handle_lock_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "Lock entire flash device.",
},
{
.name = "unlock",
- .handler = stm32x_handle_unlock_command,
+ .handler = stm32h7_handle_unlock_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "Unlock entire protected flash device.",
},
{
.name = "mass_erase",
- .handler = stm32x_handle_mass_erase_command,
+ .handler = stm32h7_handle_mass_erase_command,
.mode = COMMAND_EXEC,
.usage = "bank_id",
.help = "Erase entire flash device.",
},
{
.name = "option_read",
- .handler = stm32x_handle_option_read_command,
+ .handler = stm32h7_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,
+ .handler = stm32h7_handle_option_write_command,
.mode = COMMAND_EXEC,
.usage = "bank_id reg_offset value [mask]",
.help = "Write device option bit fields with provided value.",
@@ -1222,29 +1222,29 @@ static const struct command_registration stm32h7x_exec_command_handlers[] = {
COMMAND_REGISTRATION_DONE
};
-static const struct command_registration stm32h7x_command_handlers[] = {
+static const struct command_registration stm32h7_command_handlers[] = {
{
.name = "stm32h7x",
.mode = COMMAND_ANY,
.help = "stm32h7x flash command group",
.usage = "",
- .chain = stm32h7x_exec_command_handlers,
+ .chain = stm32h7_exec_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
const struct flash_driver stm32h7x_flash = {
.name = "stm32h7x",
- .commands = stm32h7x_command_handlers,
- .flash_bank_command = stm32x_flash_bank_command,
- .erase = stm32x_erase,
- .protect = stm32x_protect,
- .write = stm32x_write,
+ .commands = stm32h7_command_handlers,
+ .flash_bank_command = stm32h7_flash_bank_command,
+ .erase = stm32h7_erase,
+ .protect = stm32h7_protect,
+ .write = stm32h7_write,
.read = default_flash_read,
- .probe = stm32x_probe,
- .auto_probe = stm32x_auto_probe,
+ .probe = stm32h7_probe,
+ .auto_probe = stm32h7_auto_probe,
.erase_check = default_flash_blank_check,
- .protect_check = stm32x_protect_check,
- .info = stm32x_get_info,
+ .protect_check = stm32h7_protect_check,
+ .info = stm32h7_get_info,
.free_driver_priv = default_flash_free_driver_priv,
};
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/stm32h7x.c | 384 +++++++++++++++++++++++------------------------
1 file changed, 192 insertions(+), 192 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-06 08:09:00
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via e4e0faeba66799f0366b8c89992a7652db884d1a (commit)
from 22afaae7fa7b4db9918e3f1265297ffa260e818e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit e4e0faeba66799f0366b8c89992a7652db884d1a
Author: HAOUES Ahmed <ahm...@st...>
Date: Wed Jun 25 15:33:25 2025 +0100
flash/stm32h7x: Refactor STM32H7 flash register definitions to use enum
Replace individual #define constants for STM32H7 flash registers with an
enum to improve code readability and maintainability.
While there, replace a magic number with the macro
MASS_ERASE_TIMEOUT.
while there, remove the unneeded inline attribute
Change-Id: Ib35cbdace5c2f4d12aa91c370d6ec0ce348b397f
Signed-off-by: HAOUES Ahmed <ahm...@st...>
Reviewed-on: https://review.openocd.org/c/openocd/+/8888
Tested-by: jenkins
Reviewed-by: Tomas Vanek <va...@fb...>
diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c
index c02fae992..da674725d 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -12,27 +12,47 @@
#include <target/algorithm.h>
#include <target/cortex_m.h>
-
/* Erase time can be as high as 1000ms, 10x this and it's toast... */
#define FLASH_ERASE_TIMEOUT 10000
#define FLASH_WRITE_TIMEOUT 5
+#define MASS_ERASE_TIMEOUT 30000
+
+enum stm32h7_flash_reg_index {
+ STM32_FLASH_ACR_INDEX,
+ STM32_FLASH_KEYR_INDEX,
+ STM32_FLASH_OPTKEYR_INDEX,
+ STM32_FLASH_SR_INDEX,
+ STM32_FLASH_CR_INDEX,
+ STM32_FLASH_ICR_INDEX,
+ STM32_FLASH_CCR_INDEX,
+ STM32_FLASH_OPTCR_INDEX,
+ STM32_FLASH_OPTSR_INDEX,
+ STM32_FLASH_OPTSR_CUR_INDEX,
+ STM32_FLASH_OPTSR_PRG_INDEX,
+ STM32_FLASH_OPTCCR_INDEX,
+ STM32_FLASH_WPSN_CUR_INDEX,
+ STM32_FLASH_WPSN_PRG_INDEX,
+ STM32_FLASH_ISR_INDEX,
+ STM32_FLASH_REG_INDEX_NUM,
+};
/* RM 433 */
/* Same Flash registers for both banks, */
/* access depends on Flash Base address */
-#define FLASH_ACR 0x00
-#define FLASH_KEYR 0x04
-#define FLASH_OPTKEYR 0x08
-#define FLASH_CR 0x0C
-#define FLASH_SR 0x10
-#define FLASH_CCR 0x14
-#define FLASH_OPTCR 0x18
-#define FLASH_OPTSR_CUR 0x1C
-#define FLASH_OPTSR_PRG 0x20
-#define FLASH_OPTCCR 0x24
-#define FLASH_WPSN_CUR 0x38
-#define FLASH_WPSN_PRG 0x3C
-
+static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
+ [STM32_FLASH_ACR_INDEX] = 0x00,
+ [STM32_FLASH_KEYR_INDEX] = 0x04,
+ [STM32_FLASH_OPTKEYR_INDEX] = 0x08,
+ [STM32_FLASH_SR_INDEX] = 0x10,
+ [STM32_FLASH_CR_INDEX] = 0x0C,
+ [STM32_FLASH_CCR_INDEX] = 0x14,
+ [STM32_FLASH_OPTCR_INDEX] = 0x18,
+ [STM32_FLASH_OPTSR_CUR_INDEX] = 0x1C,
+ [STM32_FLASH_OPTSR_PRG_INDEX] = 0x20,
+ [STM32_FLASH_OPTCCR_INDEX] = 0x24,
+ [STM32_FLASH_WPSN_CUR_INDEX] = 0x38,
+ [STM32_FLASH_WPSN_PRG_INDEX] = 0x3C
+};
/* FLASH_CR register bits */
#define FLASH_LOCK (1 << 0)
@@ -117,6 +137,7 @@ struct stm32h7x_part_info {
uint32_t wps_mask;
/* function to compute flash_cr register values */
uint32_t (*compute_flash_cr)(uint32_t cmd, int snb);
+ int (*get_flash_error_status)(struct flash_bank *bank, uint32_t *status);
};
struct stm32h7x_flash_bank {
@@ -124,6 +145,7 @@ struct stm32h7x_flash_bank {
uint32_t idcode;
uint32_t user_bank_size;
uint32_t flash_regs_base; /* Address of flash reg controller */
+ const uint32_t *flash_regs;
const struct stm32h7x_part_info *part_info;
};
@@ -161,51 +183,56 @@ static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t cmd, int snb)
return cmd | (tmp >> 2) | (snb << 6);
}
+static int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status);
+
static const struct stm32h7x_part_info stm32h7x_parts[] = {
{
- .id = DEVID_STM32H74_H75XX,
- .revs = stm32h74_h75xx_revs,
- .num_revs = ARRAY_SIZE(stm32h74_h75xx_revs),
- .device_str = "STM32H74x/75x",
- .page_size_kb = 128,
- .block_size = 32,
- .max_flash_size_kb = 2048,
- .max_bank_size_kb = 1024,
- .has_dual_bank = true,
- .fsize_addr = 0x1FF1E880,
- .wps_group_size = 1,
- .wps_mask = 0xFF,
- .compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
+ .id = DEVID_STM32H74_H75XX,
+ .revs = stm32h74_h75xx_revs,
+ .num_revs = ARRAY_SIZE(stm32h74_h75xx_revs),
+ .device_str = "STM32H74x/75x",
+ .page_size_kb = 128,
+ .block_size = 32,
+ .max_flash_size_kb = 2048,
+ .max_bank_size_kb = 1024,
+ .has_dual_bank = true,
+ .fsize_addr = 0x1FF1E880,
+ .wps_group_size = 1,
+ .wps_mask = 0xFF,
+ .compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
+ .get_flash_error_status = stm32x_get_flash_status,
},
{
- .id = DEVID_STM32H7A_H7BXX,
- .revs = stm32h7a_h7bxx_revs,
- .num_revs = ARRAY_SIZE(stm32h7a_h7bxx_revs),
- .device_str = "STM32H7Ax/7Bx",
- .page_size_kb = 8,
- .block_size = 16,
- .max_flash_size_kb = 2048,
- .max_bank_size_kb = 1024,
- .has_dual_bank = true,
- .fsize_addr = 0x08FFF80C,
- .wps_group_size = 4,
- .wps_mask = 0xFFFFFFFF,
- .compute_flash_cr = stm32h7a_h7bxx_compute_flash_cr,
+ .id = DEVID_STM32H7A_H7BXX,
+ .revs = stm32h7a_h7bxx_revs,
+ .num_revs = ARRAY_SIZE(stm32h7a_h7bxx_revs),
+ .device_str = "STM32H7Ax/7Bx",
+ .page_size_kb = 8,
+ .block_size = 16,
+ .max_flash_size_kb = 2048,
+ .max_bank_size_kb = 1024,
+ .has_dual_bank = true,
+ .fsize_addr = 0x08FFF80C,
+ .wps_group_size = 4,
+ .wps_mask = 0xFFFFFFFF,
+ .compute_flash_cr = stm32h7a_h7bxx_compute_flash_cr,
+ .get_flash_error_status = stm32x_get_flash_status,
},
{
- .id = DEVID_STM32H72_H73XX,
- .revs = stm32h72_h73xx_revs,
- .num_revs = ARRAY_SIZE(stm32h72_h73xx_revs),
- .device_str = "STM32H72x/73x",
- .page_size_kb = 128,
- .block_size = 32,
- .max_flash_size_kb = 1024,
- .max_bank_size_kb = 1024,
- .has_dual_bank = false,
- .fsize_addr = 0x1FF1E880,
- .wps_group_size = 1,
- .wps_mask = 0xFF,
- .compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
+ .id = DEVID_STM32H72_H73XX,
+ .revs = stm32h72_h73xx_revs,
+ .num_revs = ARRAY_SIZE(stm32h72_h73xx_revs),
+ .device_str = "STM32H72x/73x",
+ .page_size_kb = 128,
+ .block_size = 32,
+ .max_flash_size_kb = 1024,
+ .max_bank_size_kb = 1024,
+ .has_dual_bank = false,
+ .fsize_addr = 0x1FF1E880,
+ .wps_group_size = 1,
+ .wps_mask = 0xFF,
+ .compute_flash_cr = stm32h74_h75xx_compute_flash_cr,
+ .get_flash_error_status = stm32x_get_flash_status,
},
};
@@ -233,7 +260,7 @@ static inline uint32_t stm32x_get_flash_reg(struct flash_bank *bank, uint32_t re
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)
+static int stm32x_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value)
{
uint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset);
int retval = target_read_u32(bank->target, reg_addr, value);
@@ -244,7 +271,14 @@ static inline int stm32x_read_flash_reg(struct flash_bank *bank, uint32_t reg_of
return retval;
}
-static inline int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
+static inline int stm32x_read_flash_reg_by_index(struct flash_bank *bank,
+ enum stm32h7_flash_reg_index reg_index, uint32_t *value)
+{
+ struct stm32h7x_flash_bank *stm32h7_info = bank->driver_priv;
+ return stm32x_read_flash_reg(bank, stm32h7_info->flash_regs[reg_index], value);
+}
+
+static int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
{
uint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset);
int retval = target_write_u32(bank->target, reg_addr, value);
@@ -255,9 +289,16 @@ static inline int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t reg_o
return retval;
}
-static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)
+static inline int stm32x_write_flash_reg_by_index(struct flash_bank *bank,
+ enum stm32h7_flash_reg_index reg_index, uint32_t value)
+{
+ struct stm32h7x_flash_bank *stm32h7_info = bank->driver_priv;
+ return stm32x_write_flash_reg(bank, stm32h7_info->flash_regs[reg_index], value);
+}
+
+static int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)
{
- return stm32x_read_flash_reg(bank, FLASH_SR, status);
+ return stm32x_read_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, status);
}
static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout)
@@ -291,7 +332,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 */
- stm32x_write_flash_reg(bank, FLASH_CCR, status);
+ stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, status);
}
return retval;
}
@@ -303,7 +344,7 @@ static int stm32x_unlock_reg(struct flash_bank *bank)
/* first check if not already unlocked
* otherwise writing on FLASH_KEYR will fail
*/
- int retval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl);
+ int retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, &ctrl);
if (retval != ERROR_OK)
return retval;
@@ -311,15 +352,15 @@ static int stm32x_unlock_reg(struct flash_bank *bank)
return ERROR_OK;
/* unlock flash registers for bank */
- retval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY1);
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, KEY1);
if (retval != ERROR_OK)
return retval;
- retval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY2);
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, KEY2);
if (retval != ERROR_OK)
return retval;
- retval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl);
+ retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, &ctrl);
if (retval != ERROR_OK)
return retval;
@@ -334,7 +375,7 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank)
{
uint32_t ctrl;
- int retval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl);
+ int retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, &ctrl);
if (retval != ERROR_OK)
return retval;
@@ -342,15 +383,15 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank)
return ERROR_OK;
/* unlock option registers */
- retval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY1);
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTKEYR_INDEX, OPTKEY1);
if (retval != ERROR_OK)
return retval;
- retval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY2);
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTKEYR_INDEX, OPTKEY2);
if (retval != ERROR_OK)
return retval;
- retval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl);
+ retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, &ctrl);
if (retval != ERROR_OK)
return retval;
@@ -364,12 +405,12 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank)
static inline int stm32x_lock_reg(struct flash_bank *bank)
{
- return stm32x_write_flash_reg(bank, FLASH_CR, FLASH_LOCK);
+ return stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, FLASH_LOCK);
}
static inline int stm32x_lock_option_reg(struct flash_bank *bank)
{
- return stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_LOCK);
+ return stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, OPT_LOCK);
}
static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
@@ -382,17 +423,17 @@ static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uin
goto flash_options_lock;
/* write option bytes */
- retval = stm32x_write_flash_reg(bank, reg_offset, value);
+ retval = stm32x_write_flash_reg_by_index(bank, reg_offset, value);
if (retval != ERROR_OK)
goto flash_options_lock;
/* Remove OPT error flag before programming */
- retval = stm32x_write_flash_reg(bank, FLASH_OPTCCR, OPT_CLR_OPTCHANGEERR);
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTCCR_INDEX, OPT_CLR_OPTCHANGEERR);
if (retval != ERROR_OK)
goto flash_options_lock;
/* start programming cycle */
- retval = stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_START);
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, OPT_START);
if (retval != ERROR_OK)
goto flash_options_lock;
@@ -400,7 +441,7 @@ static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uin
int timeout = FLASH_ERASE_TIMEOUT;
uint32_t status;
for (;;) {
- retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_CUR, &status);
+ retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_OPTSR_CUR_INDEX, &status);
if (retval != ERROR_OK) {
LOG_ERROR("stm32x_options_program: failed to read FLASH_OPTSR_CUR");
goto flash_options_lock;
@@ -434,7 +475,7 @@ static int stm32x_modify_option(struct flash_bank *bank, uint32_t reg_offset, ui
{
uint32_t data;
- int retval = stm32x_read_flash_reg(bank, reg_offset, &data);
+ int retval = stm32x_read_flash_reg_by_index(bank, reg_offset, &data);
if (retval != ERROR_OK)
return retval;
@@ -448,7 +489,7 @@ static int stm32x_protect_check(struct flash_bank *bank)
uint32_t protection;
/* read 'write protection' settings */
- int retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection);
+ int retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_WPSN_CUR_INDEX, &protection);
if (retval != ERROR_OK) {
LOG_DEBUG("unable to read WPSN_CUR register");
return retval;
@@ -488,13 +529,13 @@ static int stm32x_erase(struct flash_bank *bank, unsigned int first,
*/
for (unsigned int i = first; i <= last; i++) {
LOG_DEBUG("erase sector %u", i);
- retval = stm32x_write_flash_reg(bank, FLASH_CR,
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64, i));
if (retval != ERROR_OK) {
LOG_ERROR("Error erase sector %u", i);
goto flash_lock;
}
- retval = stm32x_write_flash_reg(bank, FLASH_CR,
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64 | FLASH_START, i));
if (retval != ERROR_OK) {
LOG_ERROR("Error erase sector %u", i);
@@ -529,7 +570,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
}
/* read 'write protection' settings */
- int retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection);
+ int retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_WPSN_CUR_INDEX, &protection);
if (retval != ERROR_OK) {
LOG_DEBUG("unable to read WPSN_CUR register");
return retval;
@@ -548,7 +589,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%" PRIx32, protection);
/* apply new option value */
- return stm32x_write_option(bank, FLASH_WPSN_PRG, protection);
+ return stm32x_write_option(bank, STM32_FLASH_WPSN_PRG_INDEX, protection);
}
static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
@@ -641,7 +682,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 = 0x%08" PRIx32, flash_sr);
/* Clear error + EOP flags but report errors */
- stm32x_write_flash_reg(bank, FLASH_CCR, flash_sr);
+ stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, flash_sr);
retval = ERROR_FAIL;
}
}
@@ -711,7 +752,7 @@ 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,
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
stm32x_info->part_info->compute_flash_cr(FLASH_PG | FLASH_PSIZE_64, 0));
if (retval != ERROR_OK)
goto flash_lock;
@@ -769,6 +810,8 @@ static int stm32x_probe(struct flash_bank *bank)
device_id = stm32x_info->idcode & 0xfff;
+ stm32x_info->flash_regs = stm32h7_flash_regs;
+
for (unsigned int n = 0; n < ARRAY_SIZE(stm32h7x_parts); n++) {
if (device_id == stm32h7x_parts[n].id)
stm32x_info->part_info = &stm32h7x_parts[n];
@@ -967,7 +1010,7 @@ static int stm32x_set_rdp(struct flash_bank *bank, enum stm32h7x_opt_rdp new_rdp
return ERROR_TARGET_NOT_HALTED;
}
- retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_PRG, &optsr);
+ retval = stm32x_read_flash_reg_by_index(bank, STM32_FLASH_OPTSR_PRG_INDEX, &optsr);
if (retval != ERROR_OK) {
LOG_DEBUG("unable to read FLASH_OPTSR_PRG register");
@@ -997,7 +1040,7 @@ static int stm32x_set_rdp(struct flash_bank *bank, enum stm32h7x_opt_rdp 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);
+ return stm32x_write_option(bank, STM32_FLASH_OPTSR_PRG_INDEX, optsr);
}
COMMAND_HANDLER(stm32x_handle_lock_command)
@@ -1056,17 +1099,17 @@ 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,
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
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,
+ retval = stm32x_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
stm32x_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64 | FLASH_START, 0));
if (retval != ERROR_OK)
goto flash_lock;
- retval = stm32x_wait_flash_op_queue(bank, 30000);
+ retval = stm32x_wait_flash_op_queue(bank, MASS_ERASE_TIMEOUT);
if (retval != ERROR_OK)
goto flash_lock;
@@ -1110,7 +1153,7 @@ COMMAND_HANDLER(stm32x_handle_option_read_command)
uint32_t reg_offset, value;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset);
- retval = stm32x_read_flash_reg(bank, reg_offset, &value);
+ retval = stm32x_read_flash_reg_by_index(bank, reg_offset, &value);
if (retval != ERROR_OK)
return retval;
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/stm32h7x.c | 215 ++++++++++++++++++++++++++++-------------------
1 file changed, 129 insertions(+), 86 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-02 13:50:56
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 22afaae7fa7b4db9918e3f1265297ffa260e818e (commit)
from 1ee0499cd80582e5e4c0eafb5b0cadd3c6478f57 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 22afaae7fa7b4db9918e3f1265297ffa260e818e
Author: Lucien Dufour <luc...@du...>
Date: Wed Aug 27 14:19:18 2025 +0200
Use C99 style for loop var
Use ARRAY_SIZE() to ensure ranges are correct.
Also, the C99 style is hopefully more readable.
Change-Id: I3d6bfbdc8e723791ba14d5a32e311c61bc2dfd77
Signed-off-by: Lucien Dufour <luc...@du...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9097
Reviewed-by: Tomas Vanek <va...@fb...>
Tested-by: jenkins
Reviewed-by: zapb <de...@za...>
diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c
index 8e03184d3..d1a81614e 100644
--- a/src/target/armv4_5.c
+++ b/src/target/armv4_5.c
@@ -659,15 +659,14 @@ static const struct reg_arch_type arm_reg_type = {
struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm)
{
- int num_regs = ARRAY_SIZE(arm_core_regs);
- int num_core_regs = num_regs;
+ unsigned int num_regs = ARRAY_SIZE(arm_core_regs);
+ unsigned int num_core_regs = num_regs;
if (arm->arm_vfp_version == ARM_VFP_V3)
num_regs += ARRAY_SIZE(arm_vfp_v3_regs);
struct reg_cache *cache = malloc(sizeof(struct reg_cache));
struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
struct arm_reg *reg_arch_info = calloc(num_regs, sizeof(struct arm_reg));
- int i;
if (!cache || !reg_list || !reg_arch_info) {
free(cache);
@@ -681,7 +680,7 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm)
cache->reg_list = reg_list;
cache->num_regs = 0;
- for (i = 0; i < num_core_regs; i++) {
+ for (unsigned int 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
@@ -737,8 +736,7 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm)
cache->num_regs++;
}
- int j;
- for (i = num_core_regs, j = 0; i < num_regs; i++, j++) {
+ for (unsigned int i = num_core_regs, j = 0; i < num_regs; i++, j++) {
reg_arch_info[i].num = arm_vfp_v3_regs[j].id;
reg_arch_info[i].mode = arm_vfp_v3_regs[j].mode;
reg_arch_info[i].target = target;
@@ -1413,7 +1411,6 @@ int armv4_5_run_algorithm_inner(struct target *target,
uint32_t context[17];
uint32_t cpsr;
int exit_breakpoint_size = 0;
- int i;
int retval = ERROR_OK;
LOG_TARGET_DEBUG(target, "Running algorithm");
@@ -1442,7 +1439,7 @@ int armv4_5_run_algorithm_inner(struct target *target,
/* save r0..pc, cpsr-or-spsr, and then cpsr-for-sure;
* they'll be restored later.
*/
- for (i = 0; i <= 16; i++) {
+ for (unsigned int i = 0; i < ARRAY_SIZE(context); i++) {
struct reg *r;
r = &ARMV4_5_CORE_REG_MODE(arm->core_cache,
@@ -1454,7 +1451,7 @@ int armv4_5_run_algorithm_inner(struct target *target,
}
cpsr = buf_get_u32(arm->cpsr->value, 0, 32);
- for (i = 0; i < num_mem_params; i++) {
+ for (int i = 0; i < num_mem_params; i++) {
if (mem_params[i].direction == PARAM_IN)
continue;
retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size,
@@ -1463,7 +1460,7 @@ int armv4_5_run_algorithm_inner(struct target *target,
return retval;
}
- for (i = 0; i < num_reg_params; i++) {
+ for (int i = 0; i < num_reg_params; i++) {
if (reg_params[i].direction == PARAM_IN)
continue;
@@ -1524,7 +1521,7 @@ int armv4_5_run_algorithm_inner(struct target *target,
if (retval != ERROR_OK)
return retval;
- for (i = 0; i < num_mem_params; i++) {
+ for (int i = 0; i < num_mem_params; i++) {
if (mem_params[i].direction != PARAM_OUT) {
int retvaltemp = target_read_buffer(target, mem_params[i].address,
mem_params[i].size,
@@ -1534,7 +1531,7 @@ int armv4_5_run_algorithm_inner(struct target *target,
}
}
- for (i = 0; i < num_reg_params; i++) {
+ for (int i = 0; i < num_reg_params; i++) {
if (reg_params[i].direction != PARAM_OUT) {
struct reg *reg = register_get_by_name(arm->core_cache,
@@ -1559,7 +1556,7 @@ int armv4_5_run_algorithm_inner(struct target *target,
}
/* restore everything we saved before (17 or 18 registers) */
- for (i = 0; i <= 16; i++) {
+ for (unsigned int i = 0; i < ARRAY_SIZE(context); i++) {
uint32_t regvalue;
regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,
arm_algorithm_info->core_mode, i).value, 0, 32);
-----------------------------------------------------------------------
Summary of changes:
src/target/armv4_5.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-02 13:47:12
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 1ee0499cd80582e5e4c0eafb5b0cadd3c6478f57 (commit)
from a482b789410d1cae87961fd31af34214bfec19ed (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 1ee0499cd80582e5e4c0eafb5b0cadd3c6478f57
Author: kryvosheiaivan <Iva...@in...>
Date: Thu Jun 26 19:20:39 2025 +0300
armv8m: Add support for msplim/psplim for targets with no secext
When armv8m does not have security extension, it still has
msplim/psplim regs implemented, which is described in Cortex-M33
Devices Generic User Guide.
Document ID: 100235_0100_06_en, or at the link:
https://developer.arm.com/documentation/100235/latest/
Tested on cyw20829 along with gdb v14.2.1
Change-Id: I4f060e4df742c6773e79ce0481697361202d544c
Signed-off-by: kryvosheiaivan <Iva...@in...>
Reviewed-on: https://review.openocd.org/c/openocd/+/8887
Tested-by: jenkins
Reviewed-by: Tomas Vanek <va...@fb...>
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/src/target/armv7m.c b/src/target/armv7m.c
index dc2d84fe1..b8697c032 100644
--- a/src/target/armv7m.c
+++ b/src/target/armv7m.c
@@ -139,6 +139,9 @@ static const struct {
{ ARMV7M_FAULTMASK, "faultmask", 1, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system", NULL, },
{ ARMV7M_CONTROL, "control", 3, REG_TYPE_INT8, "system", "org.gnu.gdb.arm.m-system", NULL, },
+ { ARMV8M_MSPLIM, "msplim", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.m-system", NULL, },
+ { ARMV8M_PSPLIM, "psplim", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.m-system", NULL, },
+
/* ARMv8-M security extension (TrustZone) specific registers */
{ ARMV8M_MSP_NS, "msp_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext", NULL, },
{ ARMV8M_PSP_NS, "psp_ns", 32, REG_TYPE_DATA_PTR, "stack", "org.gnu.gdb.arm.secext", NULL, },
@@ -288,6 +291,12 @@ uint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id)
case ARMV8M_MSP_NS...ARMV8M_PSPLIM_NS:
return arm_reg_id - ARMV8M_MSP_NS + ARMV8M_REGSEL_MSP_NS;
+ case ARMV8M_PSPLIM:
+ return ARMV8M_REGSEL_PSPLIM;
+
+ case ARMV8M_MSPLIM:
+ return ARMV8M_REGSEL_MSPLIM;
+
case ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S:
return ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_S;
diff --git a/src/target/armv7m.h b/src/target/armv7m.h
index 942e22584..8020cf034 100644
--- a/src/target/armv7m.h
+++ b/src/target/armv7m.h
@@ -59,6 +59,8 @@ enum {
ARMV8M_REGSEL_PSPLIM_S,
ARMV8M_REGSEL_MSPLIM_NS,
ARMV8M_REGSEL_PSPLIM_NS,
+ ARMV8M_REGSEL_MSPLIM = ARMV8M_REGSEL_MSPLIM_NS,
+ ARMV8M_REGSEL_PSPLIM = ARMV8M_REGSEL_PSPLIM_NS,
ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL = 0x14,
ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_S = 0x22,
@@ -150,6 +152,8 @@ enum {
/* The end of block of container and contained registers */
/* ARMv8-M specific registers */
+ ARMV8M_MSPLIM,
+ ARMV8M_PSPLIM,
ARMV8M_MSP_NS,
ARMV8M_PSP_NS,
ARMV8M_MSP_S,
@@ -207,8 +211,8 @@ enum {
ARMV7M_CORE_LAST_REG = ARMV7M_XPSR,
ARMV7M_FPU_FIRST_REG = ARMV7M_D0,
ARMV7M_FPU_LAST_REG = ARMV8M_VPR,
- ARMV8M_FIRST_REG = ARMV8M_MSP_NS,
- ARMV8M_LAST_REG = ARMV8M_CONTROL_NS,
+ ARMV8M_TZ_FIRST_REG = ARMV8M_MSP_NS,
+ ARMV8M_TZ_LAST_REG = ARMV8M_CONTROL_NS,
};
enum {
diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 42e957260..21b611b29 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -2613,6 +2613,21 @@ static bool cortex_m_has_tz(struct target *target)
return (dauthstatus & DAUTHSTATUS_SID_MASK) != 0;
}
+static bool cortex_m_main_extension(struct target *target, uint32_t cpuid)
+{
+ /* Inspect architecture to differentiate main extension/baseline */
+ unsigned int extension = (cpuid & ARM_CPUID_ARCHITECTURE_MASK) >> ARM_CPUID_ARCHITECTURE_POS;
+
+ if (extension == ARM_CPUID_MAIN_EXTENSION)
+ return true;
+ else if (extension == ARM_CPUID_NO_MAIN_EXTENSION)
+ return false;
+
+ LOG_TARGET_WARNING(target, "Fail to detect target extension");
+
+ return false;
+}
+
int cortex_m_set_secure(struct target *target, struct cortex_m_saved_security *ssec)
{
if (ssec) {
@@ -2872,10 +2887,45 @@ int cortex_m_examine(struct target *target)
if (armv7m->fp_feature != FPV5_MVE_F && armv7m->fp_feature != FPV5_MVE_I)
armv7m->arm.core_cache->reg_list[ARMV8M_VPR].exist = false;
- if (!cortex_m_has_tz(target))
- for (size_t idx = ARMV8M_FIRST_REG; idx <= ARMV8M_LAST_REG; idx++)
+ if (cortex_m->core_info->arch == ARM_ARCH_V8M) {
+ bool cm_has_tz = cortex_m_has_tz(target);
+ bool main_ext = cortex_m_main_extension(target, cpuid);
+ bool baseline = !main_ext;
+
+ if (!cm_has_tz) {
+ for (size_t idx = ARMV8M_TZ_FIRST_REG; idx <= ARMV8M_TZ_LAST_REG; idx++)
+ armv7m->arm.core_cache->reg_list[idx].exist = false;
+
+ if (baseline) {
+ armv7m->arm.core_cache->reg_list[ARMV8M_MSPLIM].exist = false;
+ armv7m->arm.core_cache->reg_list[ARMV8M_PSPLIM].exist = false;
+ }
+ } else {
+ if (baseline) {
+ /* ARMV8M without main extension but with the security extension has
+ only two stack limit registers in Secure state */
+ armv7m->arm.core_cache->reg_list[ARMV8M_MSPLIM_NS].exist = false;
+ armv7m->arm.core_cache->reg_list[ARMV8M_PSPLIM_NS].exist = false;
+ armv7m->arm.core_cache->reg_list[ARMV8M_MSPLIM].exist = false;
+ armv7m->arm.core_cache->reg_list[ARMV8M_PSPLIM].exist = false;
+ } else {
+ /* There is no separate regsel for msplim/psplim of ARMV8M mainline
+ with the security extension that would point to correct alias
+ depending on security state of the processor, thus register marked
+ as non-existing letting to choose between S/NS alias manually */
+ armv7m->arm.core_cache->reg_list[ARMV8M_MSPLIM].exist = false;
+ armv7m->arm.core_cache->reg_list[ARMV8M_PSPLIM].exist = false;
+ }
+ }
+ } else {
+ /* Security extension and stack limit checking introduced in ARMV8M */
+ for (size_t idx = ARMV8M_TZ_FIRST_REG; idx <= ARMV8M_TZ_LAST_REG; idx++)
armv7m->arm.core_cache->reg_list[idx].exist = false;
+ armv7m->arm.core_cache->reg_list[ARMV8M_MSPLIM].exist = false;
+ armv7m->arm.core_cache->reg_list[ARMV8M_PSPLIM].exist = false;
+ }
+
if (!armv7m->is_hla_target) {
if (cortex_m->core_info->flags & CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K)
/* Cortex-M3/M4 have 4096 bytes autoincrement range,
diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h
index e0a4e8552..615369f34 100644
--- a/src/target/cortex_m.h
+++ b/src/target/cortex_m.h
@@ -37,6 +37,11 @@
#define ARM_CPUID_PARTNO_POS 4
#define ARM_CPUID_PARTNO_MASK (0xFFF << ARM_CPUID_PARTNO_POS)
+#define ARM_CPUID_ARCHITECTURE_POS 16
+#define ARM_CPUID_ARCHITECTURE_MASK (0xF << ARM_CPUID_ARCHITECTURE_POS)
+#define ARM_CPUID_MAIN_EXTENSION 0xF
+#define ARM_CPUID_NO_MAIN_EXTENSION 0xC
+
#define ARM_MAKE_CPUID(impl, partno) ((((impl) << ARM_CPUID_IMPLEMENTER_POS) & ARM_CPUID_IMPLEMENTER_MASK) | \
(((partno) << ARM_CPUID_PARTNO_POS) & ARM_CPUID_PARTNO_MASK))
-----------------------------------------------------------------------
Summary of changes:
src/target/armv7m.c | 9 +++++++++
src/target/armv7m.h | 8 ++++++--
src/target/cortex_m.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++--
src/target/cortex_m.h | 5 +++++
4 files changed, 72 insertions(+), 4 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-02 13:43:13
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via a482b789410d1cae87961fd31af34214bfec19ed (commit)
from c168761983c50a28d2c8439fdded31dd7ec09300 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit a482b789410d1cae87961fd31af34214bfec19ed
Author: Tomas Vanek <va...@fb...>
Date: Sun Sep 14 22:40:28 2025 +0200
tcl/target: drop more useless reset-start events
These target configs implement neither device clock setting
nor boost of adapter speed in reset-init event.
Therefore it's not necessary to set back the safe speed in reset-start
Change-Id: I7dcd6f6d1a977388c7a0bc45fe46ede955bd45cb
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9129
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/tcl/target/altera_fpgasoc.cfg b/tcl/target/altera_fpgasoc.cfg
index a98b346c6..00ebb3726 100644
--- a/tcl/target/altera_fpgasoc.cfg
+++ b/tcl/target/altera_fpgasoc.cfg
@@ -48,7 +48,6 @@ 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 speed 1000 }
$_TARGETNAME1 configure -event reset-assert-post "cycv_dbginit $_TARGETNAME1"
@@ -56,7 +55,6 @@ $_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 speed 1000 }
#$_TARGETNAME2 configure -event reset-assert-post "cycv_dbginit $_TARGETNAME2"
proc cycv_dbginit {target} {
diff --git a/tcl/target/imx6.cfg b/tcl/target/imx6.cfg
index c9b6acf79..ed83d65fc 100644
--- a/tcl/target/imx6.cfg
+++ b/tcl/target/imx6.cfg
@@ -78,6 +78,5 @@ proc imx6_dbginit {target} {
# Slow speed to be sure it will work
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/npcx.cfg b/tcl/target/npcx.cfg
index 84bb0b7a5..8ca9f1498 100644
--- a/tcl/target/npcx.cfg
+++ b/tcl/target/npcx.cfg
@@ -46,9 +46,6 @@ $_TARGETNAME configure -work-area-phys 0x200c0000 -work-area-size $_WORKAREASIZE
# 4MHz / 6 = 666KHz, so use 600KHz for it
adapter speed 600
-# For safety purposes, set for the lowest cpu clock configuration
-$_TARGETNAME configure -event reset-start {adapter speed 600}
-
# use sysresetreq to perform a system reset
cortex_m reset_config sysresetreq
diff --git a/tcl/target/omap3530.cfg b/tcl/target/omap3530.cfg
index bd8b111a0..c1921b437 100644
--- a/tcl/target/omap3530.cfg
+++ b/tcl/target/omap3530.cfg
@@ -66,7 +66,6 @@ proc omap3_dbginit {target} {
# 16.8MHz/2 = 8.4MHz core clock, even before a bootloader kicks in.
# OK to speed up *after* PLL and clock tree setup.
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/omapl138.cfg b/tcl/target/omapl138.cfg
index 78c456d5c..9d89429a8 100644
--- a/tcl/target/omapl138.cfg
+++ b/tcl/target/omapl138.cfg
@@ -55,7 +55,6 @@ $_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000
# 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 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/pxa255.cfg b/tcl/target/pxa255.cfg
index 14ee13c37..a9cfc63d5 100644
--- a/tcl/target/pxa255.cfg
+++ b/tcl/target/pxa255.cfg
@@ -31,7 +31,6 @@ target create $_TARGETNAME xscale -endian $_ENDIAN \
# Until the PLL kicks in, keep the JTAG clock slow enough
# that we get no errors.
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
-----------------------------------------------------------------------
Summary of changes:
tcl/target/altera_fpgasoc.cfg | 2 --
tcl/target/imx6.cfg | 1 -
tcl/target/npcx.cfg | 3 ---
tcl/target/omap3530.cfg | 1 -
tcl/target/omapl138.cfg | 1 -
tcl/target/pxa255.cfg | 1 -
6 files changed, 9 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-02 13:42:42
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via c168761983c50a28d2c8439fdded31dd7ec09300 (commit)
from f5478eb112ce47768e44b88d6bbfcad469ed1701 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c168761983c50a28d2c8439fdded31dd7ec09300
Author: Tomas Vanek <va...@fb...>
Date: Sun Sep 14 21:54:30 2025 +0200
tcl/target/stm32g4x: drop useless reset-start event
There is no boost of adapter speed in reset-init event
so it's not necessary to set back the safe speed in reset-start
Change-Id: I8b78442471390f7183c39d67b29788cccc98d018
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9128
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
Reviewed-by: zapb <de...@za...>
Reviewed-by: Ahmed Haoues <ahm...@st...>
diff --git a/tcl/target/stm32g4x.cfg b/tcl/target/stm32g4x.cfg
index 39ed1e381..54b20eee5 100644
--- a/tcl/target/stm32g4x.cfg
+++ b/tcl/target/stm32g4x.cfg
@@ -83,11 +83,6 @@ $_TARGETNAME configure -event reset-init {
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
-----------------------------------------------------------------------
Summary of changes:
tcl/target/stm32g4x.cfg | 5 -----
1 file changed, 5 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-02 13:41:38
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via f5478eb112ce47768e44b88d6bbfcad469ed1701 (commit)
via c1cca2155bd8a60165145314d229603a6bc7f26d (commit)
from 914b8557802bf4e59b2a437fd8b6a015e9c0d773 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit f5478eb112ce47768e44b88d6bbfcad469ed1701
Author: Joao Lima <joa...@hb...>
Date: Tue Sep 30 12:13:30 2025 +0000
tcl/target/ti_k3.cfg: Add support for direct memory access via SWD
Adds support for direct memory access via SWD emulation for AM64x and
J784s4 boards, configuring addresses and parameters required for
direct memory operations.
Change-Id: Iebc16612b3990b2ef19ddc4143b66ab1bcbfe0f3
Signed-off-by: Joao Lima <joa...@hb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9021
Reviewed-by: Nishanth Menon <nm...@ti...>
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/tcl/target/ti_k3.cfg b/tcl/target/ti_k3.cfg
index 0dee74e5e..6b0ac2e52 100644
--- a/tcl/target/ti_k3.cfg
+++ b/tcl/target/ti_k3.cfg
@@ -176,6 +176,16 @@ switch $_soc {
# Uses the same JTAG ID
set _armv8_cores 0
}
+
+ # Setup DMEM access descriptions
+ # DAPBUS (Debugger) description
+ set _dmem_base_address 0x740002000
+ set _dmem_ap_address_offset 0x100
+ set _dmem_max_aps 10
+ # Emulated AP description
+ set _dmem_emu_base_address 0x760000000
+ set _dmem_emu_base_address_map_to 0x1d500000
+ set _dmem_emu_ap_list 1
}
am625 {
set _K3_DAP_TAPID 0x0bb7e02f
@@ -333,7 +343,7 @@ switch $_soc {
set ARMV8_CTIBASE {0x90420000 0x90520000 0x90620000 0x90720000
0x90820000 0x90920000 0x90a20000 0x90b20000}
- # J721s2 has 4 clusters of 2 R5 cores each.
+ # J784s4 has 4 clusters of 2 R5 cores each.
set _r5_cores 8
set R5_DBGBASE {0x9d010000 0x9d012000
0x9d410000 0x9d412000
@@ -348,6 +358,16 @@ switch $_soc {
main1_r5.0 main1_r5.1
main2_r5.0 main2_r5.1}
+ # Setup DMEM access descriptions
+ # DAPBUS (Debugger) description
+ set _dmem_base_address 0x4c40002000
+ set _dmem_ap_address_offset 0x100
+ set _dmem_max_aps 8
+ # Emulated AP description
+ set _dmem_emu_base_address 0x4c60000000
+ set _dmem_emu_base_address_map_to 0x1d600000
+ set _dmem_emu_ap_list 1
+
# sysctrl CTI base
set CM3_CTIBASE {0x20001000}
# Sysctrl power-ap unlock offsets
commit c1cca2155bd8a60165145314d229603a6bc7f26d
Author: Joao Lima <joa...@hb...>
Date: Tue Sep 30 12:13:04 2025 +0000
tcl/board/ti_*_swd_native.cfg: Add support for direct memory access via SW
Add support for SWD emulation as a transport method for
direct memory operations of boards TI AM64x and TI J784s4
Change-Id: I17fe9b2bef5c58886625bfdb88d92645ba4d7da7
Signed-off-by: Joao Lima <joa...@hb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9020
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
Reviewed-by: Nishanth Menon <nm...@ti...>
diff --git a/tcl/board/ti_am64xx_swd_native.cfg b/tcl/board/ti_am64xx_swd_native.cfg
new file mode 100644
index 000000000..d3727149e
--- /dev/null
+++ b/tcl/board/ti_am64xx_swd_native.cfg
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2022-2023 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments am642
+# Link: https://www.ti.com/product/AM642
+#
+# This configuration file is used as a self hosted debug configuration that
+# works on every AM642 platform based on firewall configuration permitted
+# in the system.
+#
+# In this system openOCD runs on one of the CPUs inside AM625 and provides
+# network ports that can then be used to debug the microcontrollers on the
+# SoC - either self hosted IDE OR remotely.
+
+# We are using dmem, which uses dapdirect_swd transport
+adapter driver dmem
+transport select swd
+
+if { ![info exists SOC] } {
+ set SOC am642
+}
+
+source [find target/ti_k3.cfg]
diff --git a/tcl/board/ti_j784s4_swd_native.cfg b/tcl/board/ti_j784s4_swd_native.cfg
new file mode 100644
index 000000000..13b2ac3b8
--- /dev/null
+++ b/tcl/board/ti_j784s4_swd_native.cfg
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2022-2023 Texas Instruments Incorporated - http://www.ti.com/
+#
+# Texas Instruments TDA4VM/J721E
+# Link: https://www.ti.com/product/TDA4VM
+#
+# This configuration file is used as a self hosted debug configuration that
+# works on every TDA4VM platform based on firewall configuration permitted
+# in the system.
+#
+# In this system openOCD runs on one of the CPUs inside TDA4VM and provides
+# network ports that can then be used to debug the microcontrollers on the
+# SoC - either self hosted IDE OR remotely.
+
+# We are using dmem, which uses dapdirect_swd transport
+adapter driver dmem
+transport select swd
+
+if { ![info exists SOC] } {
+ set SOC j784s4
+}
+source [find target/ti_k3.cfg]
-----------------------------------------------------------------------
Summary of changes:
...625_swd_native.cfg => ti_am64xx_swd_native.cfg} | 8 ++++----
...21e_swd_native.cfg => ti_j784s4_swd_native.cfg} | 2 +-
tcl/target/ti_k3.cfg | 22 +++++++++++++++++++++-
3 files changed, 26 insertions(+), 6 deletions(-)
copy tcl/board/{ti_am625_swd_native.cfg => ti_am64xx_swd_native.cfg} (80%)
copy tcl/board/{ti_j721e_swd_native.cfg => ti_j784s4_swd_native.cfg} (96%)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-02 13:40:28
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 914b8557802bf4e59b2a437fd8b6a015e9c0d773 (commit)
from 165e578d2b07408ec08ead21c9c531267f61315a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 914b8557802bf4e59b2a437fd8b6a015e9c0d773
Author: Jonathan Steinert <ha...@ku...>
Date: Tue Oct 14 09:06:33 2025 -0700
xmc4xxx: Correct some flash sector layouts
I think this may have been a typo/thinko from first implementation, but
for the 4200 the layout is 8 16KB chunks and then 1 128KB chunk. We were
previously only writing 240KB
Signed-off-by: Jonathan Steinert <ha...@ku...>
Change-Id: Ic3cff75ba21f6bc6ac440dfb30e24c328c7cd47c
Reviewed-on: https://review.openocd.org/c/openocd/+/9172
Reviewed-by: Antonio Borneo <bor...@gm...>
Reviewed-by: Karl Palsson <ka...@tw...>
Tested-by: jenkins
diff --git a/src/flash/nor/xmc4xxx.c b/src/flash/nor/xmc4xxx.c
index 54fd5a586..bf41cc7eb 100644
--- a/src/flash/nor/xmc4xxx.c
+++ b/src/flash/nor/xmc4xxx.c
@@ -231,12 +231,12 @@ struct xmc4xxx_command_seq {
};
/* Sector capacities. See section 8 of xmc4x00_rm */
-static const unsigned int sector_capacity_8[8] = {
- 16, 16, 16, 16, 16, 16, 16, 128
+static const unsigned int sector_capacity_9[9] = {
+ 16, 16, 16, 16, 16, 16, 16, 16, 128
};
-static const unsigned int sector_capacity_9[9] = {
- 16, 16, 16, 16, 16, 16, 16, 128, 256
+static const unsigned int sector_capacity_10[10] = {
+ 16, 16, 16, 16, 16, 16, 16, 16, 128, 256
};
static const unsigned int sector_capacity_12[12] = {
@@ -272,12 +272,12 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank)
LOG_DEBUG("%u sectors", bank->num_sectors);
switch (bank->num_sectors) {
- case 8:
- capacity = sector_capacity_8;
- break;
case 9:
capacity = sector_capacity_9;
break;
+ case 10:
+ capacity = sector_capacity_10;
+ break;
case 12:
capacity = sector_capacity_12;
break;
@@ -361,11 +361,11 @@ static int xmc4xxx_probe(struct flash_bank *bank)
* we understand the type of controller we're dealing with */
switch (flash_id) {
case FLASH_ID_XMC4100_4200:
- bank->num_sectors = 8;
+ bank->num_sectors = 9;
LOG_DEBUG("XMC4xxx: XMC4100/4200 detected.");
break;
case FLASH_ID_XMC4400:
- bank->num_sectors = 9;
+ bank->num_sectors = 10;
LOG_DEBUG("XMC4xxx: XMC4400 detected.");
break;
case FLASH_ID_XMC4500:
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/xmc4xxx.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-11-02 13:39:35
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 165e578d2b07408ec08ead21c9c531267f61315a (commit)
from 88b9bd396d5a1f83c49fa1b28745fd7feaca2b2e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 165e578d2b07408ec08ead21c9c531267f61315a
Author: Marc Schink <de...@za...>
Date: Wed Oct 8 08:24:39 2025 +0200
adapter/cmsis-dap: Add driver for TCP backend
The cmsis-dap driver is not added to the list of drivers if none of the
USB backends is available.
Add cmsis-dap driver also if TCP backend is available.
Change-Id: I877fac528e7102af74ee54dfcca77c5aded6a7ce
Signed-off-by: Marc Schink <de...@za...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9162
Tested-by: jenkins
Reviewed-by: Tomas Vanek <va...@fb...>
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c
index e29937b58..caf5ace99 100644
--- a/src/jtag/interfaces.c
+++ b/src/jtag/interfaces.c
@@ -62,7 +62,7 @@ struct adapter_driver *adapter_drivers[] = {
#if BUILD_CH347 == 1
&ch347_adapter_driver,
#endif
-#if BUILD_CMSIS_DAP_USB == 1 || BUILD_CMSIS_DAP_HID == 1
+#if BUILD_CMSIS_DAP_USB == 1 || BUILD_CMSIS_DAP_HID == 1 || BUILD_CMSIS_DAP_TCP == 1
&cmsis_dap_adapter_driver,
#endif
#if BUILD_DMEM == 1
-----------------------------------------------------------------------
Summary of changes:
src/jtag/interfaces.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-10-18 09:00:14
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 88b9bd396d5a1f83c49fa1b28745fd7feaca2b2e (commit)
from 85542c1c5c65ea73beb6d52b3ea5c38601313a3b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 88b9bd396d5a1f83c49fa1b28745fd7feaca2b2e
Author: Antonio Borneo <bor...@gm...>
Date: Sun Oct 12 12:10:46 2025 +0200
target: cortex-m: fix support for armv8m caches
Scan-build is unable to correctly follow the deferred loading of
queued read, finalized by the atomic write, thus it incorrectly
claims that the arrays d_u_ccsidr[] and i_ccsidr[] could carry
not initialized values:
armv7m_cache.c:154:31: warning: 1st function call argument
is an uninitialized value [core.CallAndMessage]
cache->arch[cl].d_u_size = decode_ccsidr(d_u_ccsidr[cl]);
armv7m_cache.c:172:29: warning: 1st function call argument
is an uninitialized value [core.CallAndMessage]
cache->arch[cl].i_size = decode_ccsidr(i_ccsidr[cl]);
Initialize the arrays to zero to hide these false positive.
Change-Id: I6d1e88093cb8807848643139647a571c1b566aa8
Signed-off-by: Antonio Borneo <bor...@gm...>
Fixes: 04da6e2c6246 ("target: cortex-m: add support for armv8m caches")
Reviewed-on: https://review.openocd.org/c/openocd/+/9167
Tested-by: jenkins
Reviewed-by: Tomas Vanek <va...@fb...>
diff --git a/src/target/armv7m_cache.c b/src/target/armv7m_cache.c
index cb57c0e25..cc0c9d140 100644
--- a/src/target/armv7m_cache.c
+++ b/src/target/armv7m_cache.c
@@ -111,7 +111,7 @@ int armv7m_identify_cache(struct target *target)
clidr, cache->loc);
// retrieve all available inner caches
- uint32_t d_u_ccsidr[8], i_ccsidr[8];
+ uint32_t d_u_ccsidr[8] = {0}, i_ccsidr[8] = {0};
for (unsigned int cl = 0; cl < cache->loc; cl++) {
unsigned int ctype = FIELD_GET(CLIDR_CTYPE_MASK(cl + 1), clidr);
-----------------------------------------------------------------------
Summary of changes:
src/target/armv7m_cache.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-10-18 08:59:26
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 85542c1c5c65ea73beb6d52b3ea5c38601313a3b (commit)
from 557a2082b1b41b288a9acd0400a6f5c75a8f47b7 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 85542c1c5c65ea73beb6d52b3ea5c38601313a3b
Author: Antonio Borneo <bor...@gm...>
Date: Sun Oct 12 11:30:00 2025 +0200
helper/log: mark 'fmt' argument of alloc_*printf() as not NULL
Even after commit e12ceddd5ee4 ("helper/log: mark `fmt` argument
of `alloc_vprintf()` as format string"), the GCC compiler still
reports that alloc_vprintf() could call vsnprintf() with a NULL
format parameter.
Inform the compiler that alloc_vprintf() cannot accept NULL as
format string.
Add an assert() in alloc_vprintf() so even compilers that do not
use the function attribute 'nonnull' will play safe.
While there, extend the same fixes to alloc_printf() too.
Change-Id: Idfa4fe9c6dfb2acfbf434c392237937ae03f0e8a
Signed-off-by: Antonio Borneo <bor...@gm...>
Reported-by: Parshintsev Anatoly <ana...@sy...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9166
Tested-by: jenkins
Reviewed-by: Anatoly P <ana...@sy...>
diff --git a/src/helper/log.c b/src/helper/log.c
index 2dada3540..7acb154c6 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -354,6 +354,8 @@ char *alloc_vprintf(const char *fmt, va_list ap)
int len;
char *string;
+ assert(fmt);
+
/* determine the length of the buffer needed */
va_copy(ap_copy, ap);
len = vsnprintf(NULL, 0, fmt, ap_copy);
diff --git a/src/helper/log.h b/src/helper/log.h
index 474d082ed..b8e3e339a 100644
--- a/src/helper/log.h
+++ b/src/helper/log.h
@@ -15,6 +15,7 @@
#define OPENOCD_HELPER_LOG_H
#include <helper/command.h>
+#include <helper/compiler.h>
/* To achieve C99 printf compatibility in MinGW, gnu_printf should be
* used for __attribute__((format( ... ))), with GCC v4.4 or later
@@ -86,9 +87,9 @@ 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)
- __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 0)));
+ __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 0))) __nonnull((1));
char *alloc_printf(const char *fmt, ...)
- __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 2)));
+ __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 2))) __nonnull((1));
const char *find_nonprint_char(const char *buf, unsigned int buf_len);
-----------------------------------------------------------------------
Summary of changes:
src/helper/log.c | 2 ++
src/helper/log.h | 5 +++--
2 files changed, 5 insertions(+), 2 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-10-18 08:37:48
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 557a2082b1b41b288a9acd0400a6f5c75a8f47b7 (commit)
from 3fd975941537346c7a3c37aecc944b30305a8e1e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 557a2082b1b41b288a9acd0400a6f5c75a8f47b7
Author: Antonio Borneo <bor...@gm...>
Date: Mon Aug 4 17:42:22 2025 +0200
openocd: don't test 'debug_level' directly
Use the macro 'LOG_LEVEL_IS()' to test 'debug_level'.
While there, use the macro 'LOG_LVL_*' in place of the numeric
value.
Skip all riscv code, as it is going to be updated soon from the
external fork.
Change-Id: Icad7e879e040d3b9cf1cc004c433f28725017493
Signed-off-by: Antonio Borneo <bor...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9070
Tested-by: jenkins
diff --git a/src/helper/command.c b/src/helper/command.c
index 9c29ceff8..4cce57f75 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -69,7 +69,7 @@ extern struct command_context *global_cmd_ctx;
* Do nothing in case we are not at debug level 3 */
static void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const *argv)
{
- if (debug_level < LOG_LVL_DEBUG)
+ if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
return;
char *dbg = alloc_printf("command -");
diff --git a/src/helper/log.c b/src/helper/log.c
index d8c4e09ac..2dada3540 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -113,7 +113,7 @@ static void log_puts(enum log_levels level,
if (f)
file = f + 1;
- if (debug_level >= LOG_LVL_DEBUG) {
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
/* print with count and time information */
int64_t t = timeval_ms() - start;
#ifdef _DEBUG_FREE_SPACE_
diff --git a/src/helper/log.h b/src/helper/log.h
index ac24f8e83..474d082ed 100644
--- a/src/helper/log.h
+++ b/src/helper/log.h
@@ -101,7 +101,7 @@ extern int debug_level;
#define LOG_DEBUG_IO(expr ...) \
do { \
- if (debug_level >= LOG_LVL_DEBUG_IO) \
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) \
log_printf_lf(LOG_LVL_DEBUG, \
__FILE__, __LINE__, __func__, \
expr); \
@@ -109,7 +109,7 @@ extern int debug_level;
#define LOG_DEBUG(expr ...) \
do { \
- if (debug_level >= LOG_LVL_DEBUG) \
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) \
log_printf_lf(LOG_LVL_DEBUG, \
__FILE__, __LINE__, __func__, \
expr); \
@@ -118,7 +118,7 @@ extern int debug_level;
#define LOG_CUSTOM_LEVEL(level, expr ...) \
do { \
enum log_levels _level = level; \
- if (debug_level >= _level) \
+ if (LOG_LEVEL_IS(_level)) \
log_printf_lf(_level, \
__FILE__, __LINE__, __func__, \
expr); \
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 479d2efe5..3261e6079 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -967,7 +967,7 @@ int default_interface_jtag_execute_queue(void)
struct jtag_command *cmd = jtag_command_queue_get();
int result = adapter_driver->jtag_ops->execute_queue(cmd);
- while (debug_level >= LOG_LVL_DEBUG_IO && cmd) {
+ while (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO) && cmd) {
switch (cmd->type) {
case JTAG_SCAN:
LOG_DEBUG_IO("JTAG %s SCAN to %s",
diff --git a/src/rtos/ecos.c b/src/rtos/ecos.c
index 7b993c6f2..41159bf09 100644
--- a/src/rtos/ecos.c
+++ b/src/rtos/ecos.c
@@ -539,7 +539,7 @@ static int ecos_check_app_info(struct rtos *rtos, struct ecos_params *param)
return -1;
if (param->flush_common) {
- if (debug_level >= LOG_LVL_DEBUG) {
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
for (unsigned int idx = 0; idx < ARRAY_SIZE(ecos_symbol_list); idx++) {
LOG_DEBUG("eCos: %s 0x%016" PRIX64 " %s",
rtos->symbols[idx].optional ? "OPTIONAL" : " ",
diff --git a/src/svf/svf.c b/src/svf/svf.c
index 001ffa263..7491ad651 100644
--- a/src/svf/svf.c
+++ b/src/svf/svf.c
@@ -1620,7 +1620,7 @@ static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str)
LOG_USER("(Above Padding command skipped, as per -tap argument)");
}
- if (debug_level >= LOG_LVL_DEBUG) {
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
/* for convenient debugging, execute tap if possible */
if ((svf_buffer_index > 0) &&
(((command != STATE) && (command != RUNTEST)) ||
diff --git a/src/target/arc.c b/src/target/arc.c
index 638e22099..629f79aa0 100644
--- a/src/target/arc.c
+++ b/src/target/arc.c
@@ -769,7 +769,7 @@ static int arc_exit_debug(struct target *target)
target->state = TARGET_HALTED;
CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));
- if (debug_level >= LOG_LVL_DEBUG) {
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
LOG_TARGET_DEBUG(target, "core stopped (halted) debug-reg: 0x%08" PRIx32, value);
CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, &value));
LOG_TARGET_DEBUG(target, "core STATUS32: 0x%08" PRIx32, value);
@@ -824,7 +824,7 @@ static int arc_halt(struct target *target)
CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));
/* some more debug information */
- if (debug_level >= LOG_LVL_DEBUG) {
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
LOG_TARGET_DEBUG(target, "core stopped (halted) DEGUB-REG: 0x%08" PRIx32, value);
CHECK_RETVAL(arc_get_register_value(target, "status32", &value));
LOG_TARGET_DEBUG(target, "core STATUS32: 0x%08" PRIx32, value);
@@ -1148,7 +1148,7 @@ static int arc_arch_state(struct target *target)
{
uint32_t pc_value;
- if (debug_level < LOG_LVL_DEBUG)
+ if (!LOG_LEVEL_IS(LOG_LVL_DEBUG))
return ERROR_OK;
CHECK_RETVAL(arc_get_register_value(target, "pc", &pc_value));
diff --git a/src/target/arm720t.c b/src/target/arm720t.c
index 7098aa472..3f7686fb7 100644
--- a/src/target/arm720t.c
+++ b/src/target/arm720t.c
@@ -323,7 +323,7 @@ static int arm720t_soft_reset_halt(struct target *target)
return retval;
} else
break;
- if (debug_level >= 3)
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG))
alive_sleep(100);
else
keep_alive();
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index c4bedcd85..06e76ac0d 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -637,7 +637,7 @@ int arm7_9_execute_sys_speed(struct target *target)
if ((buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))
&& (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_SYSCOMP, 1)))
break;
- if (debug_level >= 3)
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG))
alive_sleep(100);
else
keep_alive();
@@ -1088,7 +1088,7 @@ int arm7_9_soft_reset_halt(struct target *target)
retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval;
- if (debug_level >= 3)
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG))
alive_sleep(100);
else
keep_alive();
diff --git a/src/target/arm920t.c b/src/target/arm920t.c
index 67c212e0b..441e42305 100644
--- a/src/target/arm920t.c
+++ b/src/target/arm920t.c
@@ -746,7 +746,7 @@ int arm920t_soft_reset_halt(struct target *target)
return retval;
} else
break;
- if (debug_level >= 3) {
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
/* do not eat all CPU, time out after 1 se*/
alive_sleep(100);
} else
diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c
index 0b77981ae..98fe6bf68 100644
--- a/src/target/arm926ejs.c
+++ b/src/target/arm926ejs.c
@@ -544,7 +544,7 @@ int arm926ejs_soft_reset_halt(struct target *target)
return retval;
} else
break;
- if (debug_level >= 1) {
+ if (LOG_LEVEL_IS(LOG_LVL_WARNING)) {
/* do not eat all CPU, time out after 1 se*/
alive_sleep(100);
} else
diff --git a/src/target/xscale.c b/src/target/xscale.c
index 613c8d20a..712db4ee2 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -400,7 +400,7 @@ static int xscale_read_tx(struct target *target, int consume)
}
if (!((!(field0_in & 1)) && consume))
goto done;
- if (debug_level >= 3) {
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
LOG_DEBUG("waiting 100ms");
alive_sleep(100); /* avoid flooding the logs */
} else
@@ -471,7 +471,7 @@ static int xscale_write_rx(struct target *target)
}
if (!(field0_in & 1))
goto done;
- if (debug_level >= 3) {
+ if (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {
LOG_DEBUG("waiting 100ms");
alive_sleep(100); /* avoid flooding the logs */
} else
-----------------------------------------------------------------------
Summary of changes:
src/helper/command.c | 2 +-
src/helper/log.c | 2 +-
src/helper/log.h | 6 +++---
src/jtag/core.c | 2 +-
src/rtos/ecos.c | 2 +-
src/svf/svf.c | 2 +-
src/target/arc.c | 6 +++---
src/target/arm720t.c | 2 +-
src/target/arm7_9_common.c | 4 ++--
src/target/arm920t.c | 2 +-
src/target/arm926ejs.c | 2 +-
src/target/xscale.c | 4 ++--
12 files changed, 18 insertions(+), 18 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-10-13 07:57:03
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 3fd975941537346c7a3c37aecc944b30305a8e1e (commit)
from 1f5da25ed19f41499efdd482e522e016d0eb406c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 3fd975941537346c7a3c37aecc944b30305a8e1e
Author: Marc Schink <de...@za...>
Date: Wed Oct 8 07:40:44 2025 +0200
adapters/cmsis-dap: Fix build without libusb
The cmsis-dap core driver depends on libusb-related code which breaks
the build when libusb is not available.
Remove libusb dependency of the core driver to fix the build issue. For
now, use an own timeout #define with the value of LIBUSB_TIMEOUT_MS but
timeout handling should be better moved to the backends. However, this
should be addressed in a dedicated patch.
Change-Id: Ic5da392f8ab26b47466be199432432cdc08712ab
Signed-off-by: Marc Schink <de...@za...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9161
Reviewed-by: Tomas Vanek <va...@fb...>
Reviewed-by: <nik...@gm...>
Tested-by: jenkins
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index e5e82d13d..9f60a5ede 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -37,7 +37,8 @@
#include <target/cortex_m.h>
#include "cmsis_dap.h"
-#include "libusb_helper.h"
+
+#define TIMEOUT_MS 6000
/* Create a dummy backend for 'backend' command if real one does not build */
#if BUILD_CMSIS_DAP_USB == 0
@@ -363,12 +364,12 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
}
uint8_t current_cmd = dap->command[0];
- int retval = dap->backend->write(dap, txlen, LIBUSB_TIMEOUT_MS);
+ int retval = dap->backend->write(dap, txlen, TIMEOUT_MS);
if (retval < 0)
return retval;
/* get reply */
- retval = dap->backend->read(dap, LIBUSB_TIMEOUT_MS, CMSIS_DAP_BLOCKING);
+ retval = dap->backend->read(dap, TIMEOUT_MS, CMSIS_DAP_BLOCKING);
if (retval < 0)
return retval;
@@ -872,7 +873,7 @@ static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
}
}
- int retval = dap->backend->write(dap, idx, LIBUSB_TIMEOUT_MS);
+ int retval = dap->backend->write(dap, idx, TIMEOUT_MS);
if (retval < 0) {
queued_retval = retval;
goto skip;
@@ -913,7 +914,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo
}
/* get reply */
- retval = dap->backend->read(dap, LIBUSB_TIMEOUT_MS, blocking);
+ retval = dap->backend->read(dap, TIMEOUT_MS, blocking);
bool timeout = (retval == ERROR_TIMEOUT_REACHED || retval == 0);
if (timeout && blocking == CMSIS_DAP_NON_BLOCKING)
return;
-----------------------------------------------------------------------
Summary of changes:
src/jtag/drivers/cmsis_dap.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-10-11 16:18:25
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 1f5da25ed19f41499efdd482e522e016d0eb406c (commit)
from 7c16c38eda25da452945cd7148146e986efb6efe (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 1f5da25ed19f41499efdd482e522e016d0eb406c
Author: Antonio Borneo <bor...@gm...>
Date: Sun Oct 5 11:17:16 2025 +0200
configure.ac: rename 'adapterTuple' as 'adapter_driver'
Commit ce3bf664c815 ("configure.ac: rename M4 macro 'adapter' to
prevent accidental conflicts") renames the macro as 'adapterTuple'
but since the macro name is printed in error messages, this
creates cryptic errors like:
configure: error: header sys/mman.h is required
for adapterTuple "Bitbanging on EP93xx-based SBCs".
Rename it as 'adapter_driver'. It keeps valid the purpose of the
former renaming, while keeping readable the error message.
Change-Id: Idd68270fbdf879153cd59f4cacf5036aa599b251
Signed-off-by: Antonio Borneo <bor...@gm...>
Fixes: ce3bf664c815 ("configure.ac: rename M4 macro 'adapter' to prevent accidental conflicts")
Reviewed-on: https://review.openocd.org/c/openocd/+/9160
Tested-by: jenkins
diff --git a/configure.ac b/configure.ac
index cc4ed4aa2..6efcf24f2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -301,15 +301,15 @@ AS_IF([test "x$debug_malloc" = "xyes" -a "x$have_glibc" = "xyes"], [
])
m4_define([AC_ARG_ADAPTERS], [
- m4_foreach([adapterTuple], [$1],
- [AC_ARG_ENABLE(ADAPTER_OPT([adapterTuple]),
- AS_HELP_STRING([--enable-ADAPTER_OPT([adapterTuple])[[[=yes/no/auto]]]],
- [Enable building support for the ]ADAPTER_DESC([adapterTuple])[ (default is $2)]),
+ m4_foreach([adapter_driver], [$1],
+ [AC_ARG_ENABLE(ADAPTER_OPT([adapter_driver]),
+ AS_HELP_STRING([--enable-ADAPTER_OPT([adapter_driver])[[[=yes/no/auto]]]],
+ [Enable building support for the ]ADAPTER_DESC([adapter_driver])[ (default is $2)]),
[case "${enableval}" in
yes|no|auto) ;;
- *) AC_MSG_ERROR([Option --enable-ADAPTER_OPT([adapterTuple]) has invalid value "${enableval}".]) ;;
+ *) AC_MSG_ERROR([Option --enable-ADAPTER_OPT([adapter_driver]) has invalid value "${enableval}".]) ;;
esac],
- [ADAPTER_VAR([adapterTuple])=$2])
+ [ADAPTER_VAR([adapter_driver])=$2])
])
])
@@ -607,23 +607,24 @@ PKG_CHECK_MODULES([LIBJAYLINK], [libjaylink >= 0.2],
# Arg $3: What prerequisites are missing, to be shown in an error message
# if an adapter was requested but cannot be enabled.
m4_define([PROCESS_ADAPTERS], [
- m4_foreach([adapterTuple], [$1], [
+ m4_foreach([adapter_driver], [$1], [
AS_IF([test $2], [
- AS_IF([test "x$ADAPTER_VAR([adapterTuple])" != "xno"], [
- AC_DEFINE([BUILD_]ADAPTER_SYM([adapterTuple]), [1],
- [1 if you want the ]ADAPTER_DESC([adapterTuple]).)
+ AS_IF([test "x$ADAPTER_VAR([adapter_driver])" != "xno"], [
+ AC_DEFINE([BUILD_]ADAPTER_SYM([adapter_driver]), [1],
+ [1 if you want the ]ADAPTER_DESC([adapter_driver]).)
], [
- AC_DEFINE([BUILD_]ADAPTER_SYM([adapterTuple]), [0],
- [0 if you do not want the ]ADAPTER_DESC([adapterTuple]).)
+ AC_DEFINE([BUILD_]ADAPTER_SYM([adapter_driver]), [0],
+ [0 if you do not want the ]ADAPTER_DESC([adapter_driver]).)
])
], [
- AS_IF([test "x$ADAPTER_VAR([adapterTuple])" = "xyes"], [
- AC_MSG_ERROR([$3 is required for [adapterTuple] "ADAPTER_DESC([adapterTuple])".])
+ AS_IF([test "x$ADAPTER_VAR([adapter_driver])" = "xyes"], [
+ AC_MSG_ERROR([$3 is required for [adapter_driver] "ADAPTER_DESC([adapter_driver])".])
])
- ADAPTER_VAR([adapterTuple])=no
- AC_DEFINE([BUILD_]ADAPTER_SYM([adapterTuple]), [0], [0 if you do not want the ]ADAPTER_DESC([adapterTuple]).)
+ ADAPTER_VAR([adapter_driver])=no
+ AC_DEFINE([BUILD_]ADAPTER_SYM([adapter_driver]), [0],
+ [0 if you do not want the ]ADAPTER_DESC([adapter_driver]).)
])
- AM_CONDITIONAL(ADAPTER_SYM([adapterTuple]), [test "x$ADAPTER_VAR([adapterTuple])" != "xno"])
+ AM_CONDITIONAL(ADAPTER_SYM([adapter_driver]), [test "x$ADAPTER_VAR([adapter_driver])" != "xno"])
])
])
@@ -838,7 +839,7 @@ echo
echo
echo OpenOCD configuration summary
echo ---------------------------------------------------
-m4_foreach([adapterTuple], [USB1_ADAPTERS,
+m4_foreach([adapter_driver], [USB1_ADAPTERS,
HIDAPI_ADAPTERS, HIDAPI_USB1_ADAPTERS, LIBFTDI_ADAPTERS,
LIBFTDI_USB1_ADAPTERS,
LIBGPIOD_ADAPTERS,
@@ -860,8 +861,8 @@ m4_foreach([adapterTuple], [USB1_ADAPTERS,
DUMMY_ADAPTER,
OPTIONAL_LIBRARIES,
COVERAGE],
- [s=m4_format(["%-49s"], ADAPTER_DESC([adapterTuple]))
- AS_CASE([$ADAPTER_VAR([adapterTuple])],
+ [s=m4_format(["%-49s"], ADAPTER_DESC([adapter_driver]))
+ AS_CASE([$ADAPTER_VAR([adapter_driver])],
[auto], [
echo "$s"yes '(auto)'
],
@@ -873,8 +874,8 @@ m4_foreach([adapterTuple], [USB1_ADAPTERS,
],
[
AC_MSG_ERROR(m4_normalize([
- Error in [adapterTuple] "ADAPTER_ARG([adapterTuple])": Variable "ADAPTER_VAR([adapterTuple])"
- has invalid value "$ADAPTER_VAR([adapterTuple])".]))
+ Error in [adapter_driver] "ADAPTER_ARG([adapter_driver])": Variable "ADAPTER_VAR([adapter_driver])"
+ has invalid value "$ADAPTER_VAR([adapter_driver])".]))
])
])
echo
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 45 +++++++++++++++++++++++----------------------
1 file changed, 23 insertions(+), 22 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-10-11 16:18:00
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 7c16c38eda25da452945cd7148146e986efb6efe (commit)
from 910e6ba2f060d71506e4259ec2432e42242146ca (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 7c16c38eda25da452945cd7148146e986efb6efe
Author: Antonio Borneo <bor...@gm...>
Date: Sun Oct 5 11:13:44 2025 +0200
configure.ac: add adapter dependency from sys/mman.h
The adapter's driver that require the header file sys/mman.h
should check for it and don't compile if it is not present.
Add the check for sys/mman.h in configure.ac and prevent the
build of the adapter's driver that depend on it.
Change-Id: If0a518069e8fef9b41a67b633ec20e2f142a8b14
Signed-off-by: Antonio Borneo <bor...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9159
Tested-by: jenkins
diff --git a/configure.ac b/configure.ac
index 84d9739b4..cc4ed4aa2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -69,6 +69,7 @@ AC_CHECK_HEADERS([netdb.h])
AC_CHECK_HEADERS([poll.h])
AC_CHECK_HEADERS([strings.h])
AC_CHECK_HEADERS([sys/ioctl.h])
+AC_CHECK_HEADERS([sys/mman.h])
AC_CHECK_HEADERS([sys/param.h])
AC_CHECK_HEADERS([sys/select.h])
AC_CHECK_HEADERS([sys/stat.h])
@@ -632,12 +633,14 @@ PROCESS_ADAPTERS([HIDAPI_USB1_ADAPTERS], ["x$use_hidapi" = "xyes" -a "x$use_libu
PROCESS_ADAPTERS([LIBFTDI_ADAPTERS], ["x$use_libftdi" = "xyes"], [libftdi])
PROCESS_ADAPTERS([LIBFTDI_USB1_ADAPTERS], ["x$use_libftdi" = "xyes" -a "x$use_libusb1" = "xyes"], [libftdi and libusb-1.x])
PROCESS_ADAPTERS([LIBGPIOD_ADAPTERS], ["x$use_libgpiod" = "xyes"], [Linux libgpiod])
-PROCESS_ADAPTERS([DMEM_ADAPTER], ["x$is_linux" = "xyes"], [Linux /dev/mem])
+PROCESS_ADAPTERS([DMEM_ADAPTER], ["x$is_linux" = "xyes" -a "x$ac_cv_header_sys_mman_h" = "xyes"], [Linux /dev/mem])
PROCESS_ADAPTERS([SYSFSGPIO_ADAPTER], ["x$is_linux" = "xyes"], [Linux sysfs])
PROCESS_ADAPTERS([REMOTE_BITBANG_ADAPTER], [true], [unused])
PROCESS_ADAPTERS([CMSIS_DAP_TCP_ADAPTER], [true], [unused])
PROCESS_ADAPTERS([LIBJAYLINK_ADAPTERS], ["x$use_internal_libjaylink" = "xyes" -o "x$use_libjaylink" = "xyes"], [libjaylink-0.2])
-PROCESS_ADAPTERS([XVC_ADAPTERS], ["x$is_linux" = "xyes" -a "x$ac_cv_header_linux_pci_h" = "xyes"], [Linux build])
+PROCESS_ADAPTERS([XVC_ADAPTERS],
+ ["x$is_linux" = "xyes" -a "x$ac_cv_header_linux_pci_h" = "xyes" -a "x$ac_cv_header_sys_mman_h" = "xyes"],
+ [Linux build with headers linux/pci.h and sys/mman.h])
PROCESS_ADAPTERS([SERIAL_PORT_ADAPTERS], ["x$can_build_buspirate" = "xyes"],
[internal error: validation should happen beforehand])
PROCESS_ADAPTERS([PARALLEL_PORT_ADAPTER], [true], [unused])
@@ -649,8 +652,8 @@ PROCESS_ADAPTERS([JTAG_VPI_ADAPTER], [true], [unused])
PROCESS_ADAPTERS([RSHIM_ADAPTER], ["x$can_build_rshim" = "xyes"],
[internal error: validation should happen beforehand])
PROCESS_ADAPTERS([AMTJTAGACCEL_ADAPTER], [true], [unused])
-PROCESS_ADAPTERS([HOST_ARM_BITBANG_ADAPTERS], [true], [unused])
-PROCESS_ADAPTERS([HOST_ARM_OR_AARCH64_BITBANG_ADAPTERS], [true], [unused])
+PROCESS_ADAPTERS([HOST_ARM_BITBANG_ADAPTERS], ["x$ac_cv_header_sys_mman_h" = "xyes"], [header sys/mman.h])
+PROCESS_ADAPTERS([HOST_ARM_OR_AARCH64_BITBANG_ADAPTERS], ["x$ac_cv_header_sys_mman_h" = "xyes"], [header sys/mman.h])
PROCESS_ADAPTERS([DUMMY_ADAPTER], [true], [unused])
AS_IF([test "x$enable_linuxgpiod" != "xno"], [
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-10-11 16:16:28
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 910e6ba2f060d71506e4259ec2432e42242146ca (commit)
from 39ed0b0bbaac63c88d1e4b9ffe85e209bdb6b059 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 910e6ba2f060d71506e4259ec2432e42242146ca
Author: Marc Schink <de...@za...>
Date: Sun Aug 17 17:09:12 2025 +0000
adapter/parport: Add device file support
Allow to specify the parallel port by its device file. Deprecate port
number support but keep it for backward compatibility.
This is one necessary step to remove direct I/O support for the parallel
port driver.
While at it, consistently return ERROR_JTAG_INIT_FAILED in case of a
failure in parport_init().
Change-Id: Ie68087f05ece4b32ccab9d9bdfbf7e1a779e9031
Signed-off-by: Marc Schink <de...@za...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9152
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 4229f831b..9540e69f3 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -3217,11 +3217,12 @@ The pin direction is given in the following table.
@tab 2
@end multitable
-@deffn {Config Command} {parport port} port_number
-Configure the number of the parallel port.
+@deffn {Config Command} {parport port} file
+Specify the device file of the parallel port device.
+The parallel port device file is usually @file{/dev/parportX} on Linux and @file{/dev/ppiX} on FreeBSD.
-When using PPDEV to access the parallel port, use the number of the parallel port file @file{/dev/parport} (Linux) or @file{/dev/ppi} (FreeBSD).
-The default port number is 0.
+For legacy reason, the port number @var{X} can be specified instead of the device file.
+@b{Note:} Using the port number is a deprecated feature and will be removed in the future.
When using direct I/O, the number is the I/O port number.
The default port number is 0x378 (LTP1).
diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c
index b29562b84..794f8296e 100644
--- a/src/jtag/drivers/parport.c
+++ b/src/jtag/drivers/parport.c
@@ -47,8 +47,11 @@
static const struct adapter_gpio_config *adapter_gpio_config;
+#if PARPORT_USE_PPDEV == 0
static uint16_t parport_port;
+#endif
static bool parport_write_exit_state;
+static char *parport_device_file;
static uint32_t parport_toggling_time_ns = 1000;
static int wait_states;
@@ -258,13 +261,13 @@ static int parport_init(void)
if (gpio.gpio_num < 10 || gpio.gpio_num > 15 || gpio.gpio_num == 14) {
LOG_ERROR("The '%s' signal pin must be 10, 11, 12, 13, or 15",
adapter_gpio_get_name(gpio_index));
- return ERROR_FAIL;
+ goto init_fail;
}
} else {
if (gpio.gpio_num < 2 || gpio.gpio_num > 9) {
LOG_ERROR("The '%s' signal pin must be 2, 3, 4, 5, 6, 7, 8, or 9",
adapter_gpio_get_name(gpio_index));
- return ERROR_FAIL;
+ goto init_fail;
}
}
}
@@ -292,35 +295,37 @@ static int parport_init(void)
#if PARPORT_USE_PPDEV == 1
if (device_handle > 0) {
LOG_ERROR("Parallel port is already open");
- return ERROR_JTAG_INIT_FAILED;
+ goto init_fail;
}
- char device_path[256];
-
+ if (!parport_device_file) {
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
- snprintf(device_path, sizeof(device_path), "/dev/ppi%d", parport_port);
+ parport_device_file = strdup("/dev/ppi0");
#else
- snprintf(device_path, sizeof(device_path), "/dev/parport%d", parport_port);
-#endif /* __FreeBSD__, __FreeBSD_kernel__ */
+ parport_device_file = strdup("/dev/parport0");
+#endif
+ LOG_WARNING("No parallel port specified, using %s", parport_device_file);
+ LOG_WARNING("DEPRECATED! The lack of a parallel port specification is deprecated and will no longer work in the future");
+ }
- LOG_DEBUG("Using parallel port %s", device_path);
+ LOG_DEBUG("Using parallel port %s", parport_device_file);
- device_handle = open(device_path, O_WRONLY);
+ device_handle = open(parport_device_file, O_WRONLY);
if (device_handle < 0) {
int err = errno;
- LOG_ERROR("Failed to open parallel port %s (errno = %d)", device_path,
- err);
+ LOG_ERROR("Failed to open parallel port %s (errno = %d)",
+ parport_device_file, err);
LOG_ERROR("Check whether the device exists and if you have the required access rights");
- return ERROR_JTAG_INIT_FAILED;
+ goto init_fail;
}
#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
int retval = ioctl(device_handle, PPCLAIM);
if (retval < 0) {
- LOG_ERROR("Failed to claim parallel port %s", device_path);
- return ERROR_JTAG_INIT_FAILED;
+ LOG_ERROR("Failed to claim parallel port %s", parport_device_file);
+ goto init_fail;
}
int value = PARPORT_MODE_COMPAT;
@@ -328,7 +333,7 @@ static int parport_init(void)
if (retval < 0) {
LOG_ERROR("Cannot set compatible mode to device");
- return ERROR_JTAG_INIT_FAILED;
+ goto init_fail;
}
value = IEEE1284_MODE_COMPAT;
@@ -336,7 +341,7 @@ static int parport_init(void)
if (retval < 0) {
LOG_ERROR("Cannot set compatible 1284 mode to device");
- return ERROR_JTAG_INIT_FAILED;
+ goto init_fail;
}
#endif /* not __FreeBSD__, __FreeBSD_kernel__ */
@@ -359,7 +364,7 @@ static int parport_init(void)
if (ioperm(dataport, 3, 1) != 0) {
#endif /* PARPORT_USE_GIVEIO */
LOG_ERROR("Missing privileges for direct I/O");
- return ERROR_JTAG_INIT_FAILED;
+ goto init_fail;
}
// Make sure parallel port is in right mode (clear tristate and interrupt).
@@ -372,21 +377,27 @@ static int parport_init(void)
#endif /* PARPORT_USE_PPDEV */
if (parport_reset(0, 0) != ERROR_OK)
- return ERROR_FAIL;
+ goto init_fail;
if (parport_write(0, 0, 0) != ERROR_OK)
- return ERROR_FAIL;
+ goto init_fail;
if (parport_led(true) != ERROR_OK)
- return ERROR_FAIL;
+ goto init_fail;
bitbang_interface = &parport_bitbang;
return ERROR_OK;
+
+init_fail:
+ free(parport_device_file);
+ return ERROR_JTAG_INIT_FAILED;
}
static int parport_quit(void)
{
+ free(parport_device_file);
+
// Deinitialize signal pin states.
for (size_t i = 0; i < ARRAY_SIZE(all_signals); i++) {
const enum adapter_gpio_config_index gpio_index = all_signals[i].gpio_index;
@@ -421,13 +432,46 @@ COMMAND_HANDLER(parport_handle_port_command)
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- // Only if the port wasn't overwritten by command-line.
+#if PARPORT_USE_PPDEV == 1
+ if (parport_device_file) {
+ LOG_ERROR("The parallel port device file is already configured");
+ return ERROR_FAIL;
+ }
+
+ char *tmp;
+
+ // We do not use the parse_xxx() or COMMAND_PARSE_xxx() functions here since
+ // they generate an error message if parsing fails.
+ char *endptr = NULL;
+ unsigned long port_number = strtoul(CMD_ARGV[0], &endptr, 0);
+
+ if (*endptr == '\0' && endptr != CMD_ARGV[0]) {
+ LOG_WARNING("DEPRECATED! Using a port number is deprecated, use the device file instead");
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ tmp = alloc_printf("/dev/ppi%lu", port_number);
+#else
+ tmp = alloc_printf("/dev/parport%lu", port_number);
+#endif
+ } else {
+ tmp = strdup(CMD_ARGV[0]);
+ }
+
+ if (!tmp) {
+ LOG_ERROR("Failed to allocate memory");
+ return ERROR_FAIL;
+ }
+
+ free(parport_device_file);
+ parport_device_file = tmp;
+#else
if (parport_port > 0) {
command_print(CMD, "The parallel port is already configured");
return ERROR_FAIL;
}
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], parport_port);
+#endif
return ERROR_OK;
}
@@ -489,9 +533,8 @@ static const struct command_registration parport_subcommand_handlers[] = {
.name = "port",
.handler = parport_handle_port_command,
.mode = COMMAND_CONFIG,
- .help = "Configure the address of the I/O port (e.g. 0x378) "
- "or the number of the '/dev/parport' (Linux) or '/dev/ppi' (FreeBSD) device used",
- .usage = "port_number",
+ .help = "Specify the device file of the parallel port",
+ .usage = "file",
},
{
.name = "cable",
-----------------------------------------------------------------------
Summary of changes:
doc/openocd.texi | 9 +++--
src/jtag/drivers/parport.c | 93 +++++++++++++++++++++++++++++++++-------------
2 files changed, 73 insertions(+), 29 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2025-10-11 16:14:37
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 39ed0b0bbaac63c88d1e4b9ffe85e209bdb6b059 (commit)
from 6d51e6b900a1d2ec2446f042c8294109ecda7483 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 39ed0b0bbaac63c88d1e4b9ffe85e209bdb6b059
Author: Marc Schink <de...@za...>
Date: Sun Aug 17 14:11:39 2025 +0000
adapter/parport: Deprecate direct I/O support
We deprecate direct I/O support in favor of ppdev for the following
reasons:
- Linux supports ppdev since ~2.4 (released ~24 years ago) and it is
enabled by default on major distros (Ubuntu, Fedora). So it is
effectively ubiquitous
- FreeBSD provides no direct I/O support, so ppdev (ppi) is the only
viable option
- Direct I/O requires root/elevated privileges which is inadvisable
- Removing direct I/O reduces build and driver complexity and yields
a smaller, easier-to-maintain codebase
- Supporting only ppdev allows us to simplify the codebase by using
device files (e.g., /dev/parport0) instead of numeric identifiers
Windows is the only rationale to keep direct I/O, but the user base
appears minimal to nonexistent and no active contributors can test the
Windows driver.
Change-Id: Ia6d5ed6e8c5faa2a9b4919ca97c5cf9033372a64
Signed-off-by: Marc Schink <de...@za...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9151
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/configure.ac b/configure.ac
index 128c565a0..84d9739b4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -356,7 +356,7 @@ AC_ARG_ENABLE([parport_ppdev],
AC_ARG_ENABLE([parport_giveio],
AS_HELP_STRING([--enable-parport-giveio],
- [Enable use of giveio for parport (for CygWin only)]),
+ [Enable use of giveio for parport (deprecated, for CygWin only)]),
[parport_use_giveio=$enableval], [parport_use_giveio=])
AC_ARG_ENABLE([gw16012],
@@ -825,6 +825,12 @@ AS_IF([test "x$build_gw16012" = "xyes"], [
AC_MSG_WARN([Gateworks GW16012 JTAG adapter is deprecated and support will be removed in the next release!])
])
+AS_IF([test "x$parport_use_giveio" = "xyes" || test [ "x$enable_parport" != "xno" -a "x$parport_use_ppdev" = "xno"]], [
+ echo
+ echo
+ AC_MSG_WARN([Parallel port access with direct I/O is deprecated and support will be removed in the next release!])
+])
+
echo
echo
echo OpenOCD configuration summary
diff --git a/doc/openocd.texi b/doc/openocd.texi
index d6f9736b8..4229f831b 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -3225,6 +3225,7 @@ The default port number is 0.
When using direct I/O, the number is the I/O port number.
The default port number is 0x378 (LTP1).
+@b{Note:} Direct I/O support is deprecated and will be removed in the future.
@end deffn
@deffn {Config Command} {parport write_on_exit} (@option{on}|@option{off})
diff --git a/src/jtag/drivers/parport.c b/src/jtag/drivers/parport.c
index 09e312ec2..b29562b84 100644
--- a/src/jtag/drivers/parport.c
+++ b/src/jtag/drivers/parport.c
@@ -341,6 +341,8 @@ static int parport_init(void)
#endif /* not __FreeBSD__, __FreeBSD_kernel__ */
#else /* not PARPORT_USE_PPDEV */
+ LOG_WARNING("DEPRECATED: Parallel port access with direct I/O is deprecated and support will be removed in the next release");
+
if (!parport_port) {
parport_port = 0x378;
LOG_WARNING("No parallel port specified, using default 0x378 (LPT1)");
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 8 +++++++-
doc/openocd.texi | 1 +
src/jtag/drivers/parport.c | 2 ++
3 files changed, 10 insertions(+), 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|