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
(68) |
Dec
(18) |
| 2026 |
Jan
(30) |
Feb
(31) |
Mar
(9) |
Apr
(44) |
May
(51) |
Jun
(20) |
Jul
(37) |
Aug
(18) |
Sep
(48) |
Oct
|
Nov
|
Dec
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-19 06:26: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 8056a09f1d065bbb5207a44d4bbdd39d2e6f729d (commit)
from c2fc07b7df9d4cc38c2e8c12177568ec4b80112a (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 8056a09f1d065bbb5207a44d4bbdd39d2e6f729d
Author: Tomas Vanek <va...@fb...>
Date: Wed Sep 2 18:57:47 2026 +0200
flash/nor/swm050: remove useless free()
In the probe code free(bank->sectors) serves for re-probing.
This simple flash driver has a stub probe and bank->sectors
are allocated once in
FLASH_BANK_COMMAND_HANDLER(swm050_flash_bank_command)
Change-Id: Ic2ddc77235cdeca3bd6e15d2a3f2e8f019346603
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9931
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
Reviewed-by: Tomas Vanek <tom...@gm...>
diff --git a/src/flash/nor/swm050.c b/src/flash/nor/swm050.c
index 880c44e19..9784c9a8c 100644
--- a/src/flash/nor/swm050.c
+++ b/src/flash/nor/swm050.c
@@ -144,7 +144,6 @@ COMMAND_HANDLER(swm050_handle_mass_erase_command)
FLASH_BANK_COMMAND_HANDLER(swm050_flash_bank_command)
{
- free(bank->sectors);
bank->write_start_alignment = 4;
bank->write_end_alignment = 4;
bank->size = SWM050_FLASH_PAGE_SIZE * SWM050_FLASH_PAGES;
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/swm050.c | 1 -
1 file changed, 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-17 05:51: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 c2fc07b7df9d4cc38c2e8c12177568ec4b80112a (commit)
from b66fefa8f46e4734f703693b5137c92fa61ee760 (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 c2fc07b7df9d4cc38c2e8c12177568ec4b80112a
Author: Tomas Vanek <va...@fb...>
Date: Mon Sep 14 10:29:16 2026 +0200
flash/nor/str9xpec: fix use after free
The recent commit 54a33aeab039 ("flash/nor: drop some exit() calls")
introduced the following problem:
str9xpec_flash_bank_command() frees bank->driver_priv in the error
path, but then still uses str9xpec_info->options for buf_set_u32()
before returning. If str9xpec_build_block_list() fails, this becomes
a use-after-free and can crash or corrupt the bank state during setup.
Return immediately after cleanup.
Checkpatch-ignore: BAD_SIGN_OFF
Suggested-by: Github Copilot
Change-Id: I1eee0696ba381f1f8521e0fde6fee731588fda9f
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9992
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c
index 016f07410..78a03c7f8 100644
--- a/src/flash/nor/str9xpec.c
+++ b/src/flash/nor/str9xpec.c
@@ -286,12 +286,13 @@ FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
if (retval != ERROR_OK) {
free(bank->driver_priv);
bank->driver_priv = NULL;
+ return retval;
}
/* clear option byte register */
buf_set_u32(str9xpec_info->options, 0, 64, 0);
- return retval;
+ return ERROR_OK;
}
static int str9xpec_blank_check(struct flash_bank *bank, unsigned int first,
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/str9xpec.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-17 05:51: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 b66fefa8f46e4734f703693b5137c92fa61ee760 (commit)
from 40cf046076b9b93403e913a83921b3f97c7e26a0 (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 b66fefa8f46e4734f703693b5137c92fa61ee760
Author: Stepan Protsak <spr...@gm...>
Date: Thu Sep 10 20:20:57 2026 +0300
jtag/drivers/cmsis_dap: lower TLR reset message to debug level
cmsis_dap_execute_tlr_reset() announces every TAP reset at LOG_INFO.
A move to Test-Logic-Reset is a routine, expected operation issued on
every reset without TRST, at the end of scan chain examination and
repeatedly during SVF/XSVF playback, so the message is emitted many
times per session, flooding the output, and without telling the user
anything actionable.
doc/manual/style.txt reserves LOG_INFO() for insightful or necessary
information and asks to avoid flooding the log with frequently
generated messages, so LOG_DEBUG() is the appropriate level. No other
adapter driver logs a TLR reset at all, so this also removes an
inconsistency between drivers.
Change-Id: I26df6ac19c7977b6856178af209f0bfb08b6bc65
Signed-off-by: Stepan Protsak <spr...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9985
Reviewed-by: Tomas Vanek <tom...@gm...>
Tested-by: jenkins
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index bb8a25262..9afe29209 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -1568,7 +1568,7 @@ static void cmsis_dap_execute_sleep(struct jtag_command *cmd)
/* Set TMS high for five TCK clocks, to move the TAP to the Test-Logic-Reset state */
static int cmsis_dap_execute_tlr_reset(struct jtag_command *cmd)
{
- LOG_INFO("cmsis-dap JTAG TLR_RESET");
+ LOG_DEBUG("cmsis-dap JTAG TLR_RESET");
uint8_t seq = 0xff;
int retval = cmsis_dap_cmd_dap_swj_sequence(8, &seq);
-----------------------------------------------------------------------
Summary of changes:
src/jtag/drivers/cmsis_dap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-17 05:50:30
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 40cf046076b9b93403e913a83921b3f97c7e26a0 (commit)
from 2fe5eaefbd887f03ad30c9ba481ad25d9adf0f37 (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 40cf046076b9b93403e913a83921b3f97c7e26a0
Author: Stepan Protsak <spr...@gm...>
Date: Thu Sep 10 15:38:03 2026 +0300
uncrustify.cfg: rename align_number_left to align_number_right
Uncrustify 0.66 (Nov 2017) renamed the align_number_left option to
align_number_right, but the uncrustify.cfg config still uses the old name.
Note that the option renaming in Uncrustify was due to a typo,
and the value is required to stay false to keep the formatting style.
Ref. Uncrustify commits:
Link: https://github.com/uncrustify/uncrustify/commit/b5df8bba4f0fe90d021a6813fca5770e29913182
Link: https://github.com/uncrustify/uncrustify/commit/b3efa8c6577789550242f73d4a392edddf7c55e2
Change-Id: I2c2189a76d020357d3b52c656c3c3a3be14f31c5
Signed-off-by: Stepan Protsak <spr...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9983
Reviewed-by: Tomas Vanek <tom...@gm...>
Tested-by: jenkins
diff --git a/uncrustify.cfg b/uncrustify.cfg
index 593bcc2ad..68370cebd 100644
--- a/uncrustify.cfg
+++ b/uncrustify.cfg
@@ -37,7 +37,7 @@ sp_balance_nested_parens=false
align_keep_tabs=false
align_with_tabs=false
align_on_tabstop=false
-align_number_left=false
+align_number_right=false
align_func_params=false
align_same_func_call_params=false
align_var_def_colon=false
-----------------------------------------------------------------------
Summary of changes:
uncrustify.cfg | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-16 19:50:07
|
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 2fe5eaefbd887f03ad30c9ba481ad25d9adf0f37 (commit)
from 339f088acdd706b3c6389755e677a47c1f15aa5b (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 2fe5eaefbd887f03ad30c9ba481ad25d9adf0f37
Author: Tomas Vanek <va...@fb...>
Date: Sat Sep 5 09:43:19 2026 +0200
flash/nor: make flash driver erase_check method optional
Currently more than 50 flash drivers define
.erase_check = default_flash_blank_check
Fall back to default_flash_blank_check() if the .erase_check
method is NULL
While on it fix unbalanced braces around else to make
checkpatch with checking extended to hunk context happy.
Change-Id: I9df7e18c249244795b204020f91f275dd859e6f5
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9960
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h
index 1d878c591..e77a46de1 100644
--- a/src/flash/nor/driver.h
+++ b/src/flash/nor/driver.h
@@ -179,6 +179,9 @@ struct flash_driver {
* checks and then set the @c flash_sector::is_erased field
* for each of the flash banks's sectors.
*
+ * If the flash does not need device specific erase_check
+ * set method to NULL and default_flash_blank_check() will be used.
+ *
* @param bank The bank to check
* @returns ERROR_OK if successful; otherwise, an error code.
*/
diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c
index 5829d862b..0a0de8e24 100644
--- a/src/flash/nor/tcl.c
+++ b/src/flash/nor/tcl.c
@@ -187,10 +187,13 @@ COMMAND_HANDLER(handle_flash_erase_check_command)
if (retval != ERROR_OK)
return retval;
- retval = p->driver->erase_check(p);
- if (retval == ERROR_OK)
+ if (p->driver->erase_check)
+ retval = p->driver->erase_check(p);
+ else
+ retval = default_flash_blank_check(p);
+ if (retval == ERROR_OK) {
command_print(CMD, "successfully checked erase state");
- else {
+ } else {
command_print(CMD,
"Error: checking erase state of flash bank #%s at "
TARGET_ADDR_FMT,
diff --git a/src/flash/nor/virtual.c b/src/flash/nor/virtual.c
index 2c2be0520..0c2f1b913 100644
--- a/src/flash/nor/virtual.c
+++ b/src/flash/nor/virtual.c
@@ -175,8 +175,11 @@ static int virtual_blank_check(struct flash_bank *bank)
if (!master_bank)
return ERROR_FLASH_OPERATION_FAILED;
- /* call master handler */
- return master_bank->driver->erase_check(master_bank);
+ /* call master handler or default */
+ if (master_bank->driver->erase_check)
+ return master_bank->driver->erase_check(master_bank);
+
+ return default_flash_blank_check(master_bank);
}
static int virtual_flash_read(struct flash_bank *bank,
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/driver.h | 3 +++
src/flash/nor/tcl.c | 9 ++++++---
src/flash/nor/virtual.c | 7 +++++--
3 files changed, 14 insertions(+), 5 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-16 19:49:04
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 339f088acdd706b3c6389755e677a47c1f15aa5b (commit)
from a6df9b87d55b1c1641259a97693f3da0f230f151 (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 339f088acdd706b3c6389755e677a47c1f15aa5b
Author: Tomas Vanek <va...@fb...>
Date: Thu Sep 3 21:01:07 2026 +0200
flash/nor: make flash driver read method optional
Currently more than 60 flash drivers define
.read = default_flash_read
Moreover two drivers (fm3 and dsp5680xx_flash) erroneously do not
define .read at all and therefore flash read commands will
cause OpenOCD segfault.
Fall back to default_flash_read() if the .read method is NULL
Change-Id: If115a0a4325c738a5db0b383c7037a20a10f5f54
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9959
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
index 34698299b..6a9d58ee2 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -106,7 +106,10 @@ int flash_driver_read(struct flash_bank *bank,
LOG_DEBUG("call flash_driver_read()");
- retval = bank->driver->read(bank, buffer, offset, count);
+ if (bank->driver->read)
+ retval = bank->driver->read(bank, buffer, offset, count);
+ else
+ retval = default_flash_read(bank, buffer, offset, count);
if (retval != ERROR_OK) {
LOG_ERROR(
"error reading to flash at address " TARGET_ADDR_FMT
diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h
index 0d55824e2..1d878c591 100644
--- a/src/flash/nor/driver.h
+++ b/src/flash/nor/driver.h
@@ -135,6 +135,9 @@ struct flash_driver {
* "bank->base + offset", while the physical address is
* dependent upon current target MMU mappings.
*
+ * If the flash does not need device specific read processing,
+ * set method to NULL and default_flash_read() will be used.
+ *
* @param bank The bank to read.
* @param buffer The data bytes read.
* @param offset The offset into the chip to read.
diff --git a/src/flash/nor/virtual.c b/src/flash/nor/virtual.c
index 5b8a3c5b7..2c2be0520 100644
--- a/src/flash/nor/virtual.c
+++ b/src/flash/nor/virtual.c
@@ -187,8 +187,11 @@ static int virtual_flash_read(struct flash_bank *bank,
if (!master_bank)
return ERROR_FLASH_OPERATION_FAILED;
- /* call master handler */
- return master_bank->driver->read(master_bank, buffer, offset, count);
+ /* call master handler or default */
+ if (master_bank->driver->read)
+ return master_bank->driver->read(master_bank, buffer, offset, count);
+
+ return default_flash_read(master_bank, buffer, offset, count);
}
void virtual_flash_free_driver_priv(struct flash_bank *bank)
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/core.c | 5 ++++-
src/flash/nor/driver.h | 3 +++
src/flash/nor/virtual.c | 7 +++++--
3 files changed, 12 insertions(+), 3 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-16 19:47:58
|
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 a6df9b87d55b1c1641259a97693f3da0f230f151 (commit)
from 1f3f5831d25f58dbeed8de4ad6627c75e774bd2c (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 a6df9b87d55b1c1641259a97693f3da0f230f151
Author: Paulius Zaleckas <pau...@gm...>
Date: Mon Aug 10 21:55:22 2026 +0300
drivers/ch347: support SRST in SWD mode
In SWD mode the TRST pin is not needed as a JTAG signal, so it can be
driven through the GPIO command (0xCC) to provide SRST. The GPIO command
is a "single" command that is flushed on its own, so it works while the
chip is in SWD mode.
TRST is Pin9 on both chips, but has a different GPIO number: GPIO5 on the
CH347T and GPIO3 on the CH347F. Use that pin by default and allow to
select another one with 'adapter gpio srst'. Refuse a GPIO that is already
taken by the activity LED, because the LED activity would toggle the reset
line.
Honour the drive mode that 'reset_config' keeps in the GPIO configuration.
SRST defaults to open drain, which the chip cannot do by itself, so
emulate it by switching the pin to an input instead of driving it to the
inactive level. The reset line then needs a pull-up; 'reset_config
srst_push_pull' selects the previous behaviour of driving both levels.
Don't verify the readback of the GPIO command for SRST. Bit 6 of the
response is the measured pin level, not the state of the output latch, so
it legitimately differs from the requested level while the target drives
the reset line itself, e.g. during a watchdog reset loop.
The mask of the usable GPIO's was determined on the CH347T and does not
hold for the CH347F, where the GPIO's share their pins with the interface
signals: GPIO4 to GPIO7 are TCK, TDO, TDI and TMS, and TCK and TMS are
also SWDCLK and SWDIO. Selecting one of them would break the running
transport, so use a separate mask per chip variant. This also applies to
'adapter gpio led'.
Tested on a CH347T in mode 3 and on a CH347F, both with an S32K118 whose
RESET_b is wired to the TRST pin. Over SWD 'reset halt' works reliably on
both chips, driving the default GPIO: GPIO5 on the CH347T and GPIO3 on the
CH347F. A sweep of all GPIO's confirmed that no other GPIO reaches the
reset line. Both drive modes were checked against the readback of the
GPIO command: deasserting SRST leaves the pin an input in open drain mode
and drives it high in push-pull mode, and the target leaves reset in both
cases. JTAG is unaffected, the scan chain interrogation still reads the
IDCODE, TRST still works and asserting SRST is still refused.
Change-Id: Ide856b11d006ca01381c7c57e4118eadeb50fc65
Signed-off-by: Paulius Zaleckas <pau...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9700
Tested-by: jenkins
Reviewed-by: Matthias Jentsch <in...@ea...>
Reviewed-by: Tomas Vanek <tom...@gm...>
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 5e24301e3..1f0a60149 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -2617,6 +2617,27 @@ mitigates the problem.
The driver supports activity LED through the generic
command @ref{adapter gpio, @command{adapter gpio led}}.
+
+In SWD mode the TRST pin is not needed as a JTAG signal, so the driver drives
+it as a GPIO to provide SRST. TRST is pin 9 on both chips, but has a different
+GPIO number: GPIO5 on the CH347T and GPIO3 on the CH347F. Use
+@ref{adapter gpio, @command{adapter gpio srst}} to select a different GPIO or
+to change the polarity. SRST is not available in JTAG mode, where the pin
+carries TRST.
+
+Not every GPIO can be used, because the GPIO's share their pins with the
+interface signals. Only GPIO3 to GPIO6 are free on the CH347T, and GPIO0 to
+GPIO3 on the CH347F, where GPIO4 to GPIO7 are TCK, TDO, TDI and TMS. Note that
+GPIO3 of the CH347F is TRST, so it is only free when TRST is unused.
+
+SRST and the activity LED cannot share a GPIO. If both are assigned to the
+same pin, SRST gets disabled.
+
+The SRST GPIO follows the drive mode of @ref{reset_config,,@command{reset_config}}.
+The default is open drain, which the driver emulates by switching the pin to an
+input instead of driving it to the inactive level, so the reset line needs a
+pull-up. Use @command{reset_config srst_push_pull} if it has none.
+
@end deffn
@deffn {Interface Driver} {cklink}
diff --git a/src/jtag/drivers/ch347.c b/src/jtag/drivers/ch347.c
index 856d44bdc..3fa00d3b8 100644
--- a/src/jtag/drivers/ch347.c
+++ b/src/jtag/drivers/ch347.c
@@ -26,9 +26,8 @@
* | 8 MHz XTAL | *
* |_____________| *
* *
- * This CH347 driver is only tested for the CH347T chip in mode 3. *
- * The CH347 datasheet mention another chip the CH347F which was not *
- * available for testing. *
+ * This CH347 driver is tested with the CH347T chip in mode 3 and *
+ * with the CH347F chip. *
* *
* The datasheet for the wch-ic.com's CH347 part is here: *
* https://www.wch-ic.com/downloads/CH347DS1_PDF.html *
@@ -73,14 +72,26 @@
#define LED_ON 1
#define LED_OFF 0
#define GPIO_CNT 8 // the CH347 has 8 GPIO's
-/* mask which GPIO's are available in mode 3 of CH347T only GPIO3 (Pin11 / SCL), GPIO4 (Pin15 / ACT),
- GPIO5 (Pin9 / TRST) and GPIO6 (Pin2 / CTS1) are possible. Tested only with CH347T not CH347F chip.
- pin numbers are for CH347T */
-#define USEABLE_GPIOS 0x78
+/* mask which GPIO's are available in mode 3 of the CH347T: only GPIO3 (Pin11 / SCL),
+ GPIO4 (Pin15 / ACT), GPIO5 (Pin9 / TRST) and GPIO6 (Pin2 / CTS1) are possible */
+#define CH347T_USABLE_GPIOS 0x78
+/* On the CH347F the GPIO's share the pins with the interface signals: GPIO0 (Pin17),
+ GPIO1 (Pin18), GPIO2 (Pin10), GPIO3 (Pin9 / TRST), GPIO4 (Pin23 / TCK + SWDCLK),
+ GPIO5 (Pin24 / TDO), GPIO6 (Pin25 / TDI), GPIO7 (Pin26 / TMS + SWDIO). GPIO4 to GPIO7
+ always carry a signal of the JTAG or SWD interface, so only GPIO0 to GPIO3 are left.
+ GPIO3 is TRST, which is not a SWD signal. */
+#define CH347F_USABLE_GPIOS 0x0F
+/* In SWD mode the TRST pin is unused as a JTAG signal, so it can drive SRST through the GPIO
+ command. TRST is Pin9 on both chips, but has a different GPIO number: GPIO5 on CH347T,
+ GPIO3 on CH347F. */
+#define CH347T_TRST_GPIO 5
+#define CH347F_TRST_GPIO 3
/* For GPIO command: always set bits 7 and 6 for GPIO enable
bits 5 and 4 for pin direction output bit 3 is the data bit */
#define GPIO_SET_L (BIT(4) | BIT(5) | BIT(6) | BIT(7)) // value for setting a GPIO to low
#define GPIO_SET_H (BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7)) // value for setting a GPIO to high
+// enable the pin and set the direction to input, so the pin gets released
+#define GPIO_SET_INPUT (BIT(6) | BIT(7))
#define VENDOR_VERSION 0x5F // for getting the chip version
@@ -257,6 +268,9 @@ static uint16_t default_ch347_pids[] = {DEFAULT_CH347T_PRODUCT_ID,
DEFAULT_CH347F_PRODUCT_ID, DEFAULT_OTHER_PRODUCT_ID, 0};
static uint8_t ch347_activity_led_gpio_pin = 0xFF;
static bool ch347_activity_led_active_high;
+// GPIO driving SRST in SWD mode, defaults to the otherwise unused TRST pin
+static uint8_t ch347_srst_gpio_pin = 0xFF;
+static bool ch347_srst_active_high;
static struct ch347_info ch347;
static struct libusb_device_handle *ch347_handle;
@@ -1252,35 +1266,93 @@ static int ch347_scratchpad_add_scan(struct scan_command *cmd)
}
/**
- * @brief Sets a GPIO bit
+ * @brief Mask of the GPIO's that don't collide with an interface signal
+ *
+ * @return mask with a bit set for every usable GPIO
+ */
+static uint8_t ch347_usable_gpios(void)
+{
+ return ch347.chip_variant == CH347F ? CH347F_USABLE_GPIOS : CH347T_USABLE_GPIOS;
+}
+
+/**
+ * @brief Sends a GPIO command for a single pin and returns the pin state
+ * that the device reports back
+ *
+ * Only the byte of the addressed pin is filled in, all other bytes stay zero.
+ * A zero byte means "not enabled" for the device, so the other pins keep
+ * their configuration.
*
* @param gpio GPIO bit number 0-7
- * @param data true for high; false for low
+ * @param value byte for this pin, one of GPIO_SET_L, GPIO_SET_H, GPIO_SET_INPUT
+ * @param state returns the byte the device reports for this pin; BIT(6) is the pin level
* @return ERROR_OK at success
*/
-static int ch347_gpio_set(int gpio, bool data)
+static int ch347_gpio_cmd(unsigned int gpio, uint8_t value, uint8_t *state)
{
+ if (gpio >= GPIO_CNT) {
+ LOG_ERROR("GPIO %u out of range", gpio);
+ return ERROR_FAIL;
+ }
+
int retval = ch347_cmd_start_next(CH347_CMD_GPIO);
if (retval != ERROR_OK)
return retval;
uint8_t gpios[GPIO_CNT];
memset(gpios, 0, GPIO_CNT);
- /* always set bits 7 and 6 for GPIO enable
- bits 5 and 4 for pin direction output
- bit 3 is the data bit */
- gpios[gpio] = data == 0 ? GPIO_SET_L : GPIO_SET_H;
+ gpios[gpio] = value;
retval = ch347_scratchpad_add_bytes(gpios, GPIO_CNT);
if (retval != ERROR_OK)
return retval;
- // check in the read if the bit is set/cleared correctly
- uint8_t byte;
- retval = ch347_single_read_get_byte(gpio, &byte);
+ return ch347_single_read_get_byte(gpio, state);
+}
+
+/**
+ * @brief Translates an output level into a GPIO command byte for a drive mode
+ *
+ * The CH347 has no open drain output driver, so it gets emulated by switching
+ * the pin to input instead of driving the inactive level. The line then relies
+ * on an external pull resistor or on the target driving it.
+ *
+ * @param level true to output a high level, false for a low level
+ * @param drive output drive mode to emulate
+ * @return one of GPIO_SET_L, GPIO_SET_H or GPIO_SET_INPUT
+ */
+static uint8_t ch347_gpio_drive_value(bool level, enum adapter_gpio_drive_mode drive)
+{
+ switch (drive) {
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:
+ return level ? GPIO_SET_INPUT : GPIO_SET_L;
+ case ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:
+ return level ? GPIO_SET_H : GPIO_SET_INPUT;
+ case ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:
+ break;
+ }
+
+ return level ? GPIO_SET_H : GPIO_SET_L;
+}
+
+/**
+ * @brief Sets a GPIO bit
+ *
+ * @param gpio GPIO bit number 0-7
+ * @param data true for high; false for low
+ * @return ERROR_OK at success
+ */
+static int ch347_gpio_set(int gpio, bool data)
+{
+ /* always set bits 7 and 6 for GPIO enable
+ bits 5 and 4 for pin direction output
+ bit 3 is the data bit */
+ uint8_t state;
+ int retval = ch347_gpio_cmd(gpio, data ? GPIO_SET_H : GPIO_SET_L, &state);
if (retval != ERROR_OK)
return retval;
- if ((byte & BIT(6)) >> 6 != data) {
+ // check in the read if the bit is set/cleared correctly
+ if ((bool)(state & BIT(6)) != data) {
LOG_ERROR("Output not set.");
return ERROR_FAIL;
}
@@ -1306,23 +1378,48 @@ static int ch347_activity_led_set(int led_state)
/**
* @brief Control (assert/deassert) the signals SRST and TRST on the interface.
*
+ * In SWD mode TRST is not used as a JTAG signal, so the pin is driven as a
+ * GPIO to provide SRST. In JTAG mode the pin is TRST and SRST is unavailable.
+ *
+ * The SRST GPIO follows the drive mode configured with 'reset_config'.
+ *
* @param trst 1 to assert TRST, 0 to deassert TRST.
* @param srst 1 to assert SRST, 0 to deassert SRST.
- * @return Always ERROR_FAIL for asserting via SRST and TRST in SWD mode.
- * ERROR_OK for assert/deassert in JTAG mode for TRST
+ * @return ERROR_FAIL for asserting SRST in JTAG mode.
+ * ERROR_OK for assert/deassert in JTAG mode for TRST and in SWD mode for SRST
*/
static int ch347_reset(int trst, int srst)
{
LOG_DEBUG_IO("reset trst: %i srst %i", trst, srst);
- if (srst) {
- LOG_ERROR("Asserting SRST not supported!");
- return ERROR_FAIL;
- }
if (swd_mode) {
if (trst)
LOG_WARNING("Asserting TRST not supported in SWD mode!");
- return ERROR_OK;
+
+ if (ch347_srst_gpio_pin == 0xFF) {
+ if (srst) {
+ LOG_ERROR("Asserting SRST not supported: no usable GPIO configured");
+ return ERROR_FAIL;
+ }
+ return ERROR_OK;
+ }
+
+ /* Honour the drive mode of 'reset_config'. It defaults to open drain,
+ which releases the pin instead of driving the inactive level, so the
+ target can keep the line low on its own.
+ Don't verify the readback: it reports the pin level, and the target
+ is free to hold the reset line low itself, e.g. while it is in a
+ watchdog reset loop. */
+ bool level = srst ? ch347_srst_active_high : !ch347_srst_active_high;
+ uint8_t value = ch347_gpio_drive_value(level,
+ adapter_gpio_get_config()[ADAPTER_GPIO_IDX_SRST].drive);
+ uint8_t state;
+ return ch347_gpio_cmd(ch347_srst_gpio_pin, value, &state);
+ }
+
+ if (srst) {
+ LOG_ERROR("Asserting SRST not supported");
+ return ERROR_FAIL;
}
int retval = ch347_cmd_start_next(CH347_CMD_JTAG_BIT_OP);
@@ -1804,13 +1901,52 @@ static const struct command_registration ch347_command_handlers[] = {
static void ch347_configure_activity_led(const struct adapter_gpio_config *led_config)
{
uint8_t gpio = led_config->gpio_num;
- if (gpio >= GPIO_CNT || (BIT(gpio) & USEABLE_GPIOS) == 0)
+ if (gpio >= GPIO_CNT || (BIT(gpio) & ch347_usable_gpios()) == 0)
return;
ch347_activity_led_gpio_pin = gpio;
ch347_activity_led_active_high = !led_config->active_low;
}
+/**
+ * @brief Configure which GPIO pin drives SRST in SWD mode.
+ *
+ * Defaults to the TRST pin, which is unused in SWD mode. A different pin can
+ * be selected with 'adapter gpio srst'. If the configured GPIO is not usable
+ * or is already taken by the activity LED, SRST gets disabled.
+ *
+ * Must be called after ch347_configure_activity_led().
+ *
+ * @param srst_config Pointer to the GPIO configuration structure for the SRST pin
+ */
+static void ch347_configure_srst_gpio(const struct adapter_gpio_config *srst_config)
+{
+ ch347_srst_active_high = !srst_config->active_low;
+
+ unsigned int gpio;
+ if (srst_config->gpio_num == ADAPTER_GPIO_NOT_SET) {
+ // the TRST pin is free in SWD mode, so use it by default
+ gpio = ch347.chip_variant == CH347F ? CH347F_TRST_GPIO : CH347T_TRST_GPIO;
+ } else {
+ gpio = srst_config->gpio_num;
+ if (gpio >= GPIO_CNT || (BIT(gpio) & ch347_usable_gpios()) == 0) {
+ LOG_ERROR("GPIO %u can't be used for SRST, disabling SRST", gpio);
+ ch347_srst_gpio_pin = 0xFF;
+ return;
+ }
+ }
+
+ /* Driving the same pin from two functions would let the LED activity
+ toggle the reset line, so refuse to share it. */
+ if (gpio == ch347_activity_led_gpio_pin) {
+ LOG_ERROR("GPIO %u is already used as the activity LED, disabling SRST", gpio);
+ ch347_srst_gpio_pin = 0xFF;
+ return;
+ }
+
+ ch347_srst_gpio_pin = gpio;
+}
+
/**
* @brief CH347 Initialization function
*
@@ -1842,6 +1978,8 @@ static int ch347_init(void)
if (!swd_mode) {
tap_set_state(TAP_RESET);
} else {
+ ch347_configure_srst_gpio(&adapter_gpio_get_config()[ADAPTER_GPIO_IDX_SRST]);
+
retval = ch347_init_pack_size();
if (retval != ERROR_OK)
return retval;
-----------------------------------------------------------------------
Summary of changes:
doc/openocd.texi | 21 ++++++
src/jtag/drivers/ch347.c | 190 ++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 185 insertions(+), 26 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-14 08:03:30
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 1f3f5831d25f58dbeed8de4ad6627c75e774bd2c (commit)
from 54a33aeab039b7eaad7a9ee5856ed2235800e0b1 (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 1f3f5831d25f58dbeed8de4ad6627c75e774bd2c
Author: Tomas Vanek <va...@fb...>
Date: Fri Aug 21 09:54:15 2026 +0200
jtag/drivers/cmsis_dap: fix possible buffer overflow
The adapter response of CMD_SWO_Data command relied on well behaved
adapter firmware. In case of malicious modification of adapter firmware
or accidentally getting the response of another CMSIS-DAP command,
cmsis_dap_cmd_dap_swo_data() could copy more data than max_trace_count.
Limit the returned trace_data with max_trace_count.
Also check if trace_count (trace data size) fits into the adapter response.
Change-Id: Iea6e5910ee17f2b3635c7fc67c4eaa8add5d1b4e
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9856
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index fda8d68e5..bb8a25262 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -785,11 +785,23 @@ static int cmsis_dap_cmd_dap_swo_data(
return ERROR_JTAG_DEVICE_ERROR;
}
+ size_t count = le_to_h_u16(&cmsis_dap_handle->response[2]);
+ if (count > max_trace_count) {
+ LOG_WARNING("CMSIS-DAP: CMD_SWO_Data returned more %zu than requested %zu",
+ count, max_trace_count);
+ count = max_trace_count;
+ }
+ if (4 + count > cmsis_dap_handle->response_size) {
+ LOG_ERROR("CMSIS-DAP: CMD_SWO_Data payload (size %zu) does not fit into response (size %u)",
+ count, cmsis_dap_handle->response_size);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+
*trace_status = cmsis_dap_handle->response[1];
- *trace_count = le_to_h_u16(&cmsis_dap_handle->response[2]);
+ *trace_count = count;
- if (*trace_count > 0)
- memcpy(data, &cmsis_dap_handle->response[4], *trace_count);
+ if (count > 0)
+ memcpy(data, &cmsis_dap_handle->response[4], count);
return ERROR_OK;
}
-----------------------------------------------------------------------
Summary of changes:
src/jtag/drivers/cmsis_dap.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-13 04:55:07
|
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 54a33aeab039b7eaad7a9ee5856ed2235800e0b1 (commit)
from bd521b22217b64c47573d084a3ce49a03b1e0e61 (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 54a33aeab039b7eaad7a9ee5856ed2235800e0b1
Author: Tomas Vanek <va...@fb...>
Date: Fri Aug 21 17:57:41 2026 +0200
flash/nor: drop some exit() calls
and replace them by passing appropriate error codes.
Change-Id: I1cd42b6bfaf630026a01545e1dd8dc1a3ba1b760
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9860
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/flash/nor/cfi.c b/src/flash/nor/cfi.c
index 108b66750..2633d4cbc 100644
--- a/src/flash/nor/cfi.c
+++ b/src/flash/nor/cfi.c
@@ -2607,7 +2607,9 @@ int cfi_probe(struct flash_bank *bank)
return retval;
/* check device/manufacturer ID for known non-CFI flashes. */
- cfi_fixup_non_cfi(bank);
+ retval = cfi_fixup_non_cfi(bank);
+ if (retval != ERROR_OK)
+ return retval;
/* query only if this is a CFI compatible flash,
* otherwise the relevant info has already been filled in
diff --git a/src/flash/nor/non_cfi.c b/src/flash/nor/non_cfi.c
index f096ba69c..4a229de54 100644
--- a/src/flash/nor/non_cfi.c
+++ b/src/flash/nor/non_cfi.c
@@ -455,7 +455,7 @@ static const struct non_cfi non_cfi_flashes[] = {
}
};
-void cfi_fixup_non_cfi(struct flash_bank *bank)
+int cfi_fixup_non_cfi(struct flash_bank *bank)
{
unsigned int mask;
struct cfi_flash_bank *cfi_info = bank->driver_priv;
@@ -474,7 +474,7 @@ void cfi_fixup_non_cfi(struct flash_bank *bank)
/* only fixup jedec flashes found in table */
if (!non_cfi->mfr)
- return;
+ return ERROR_OK;
cfi_info->not_cfi = true;
@@ -544,6 +544,7 @@ void cfi_fixup_non_cfi(struct flash_bank *bank)
cfi_info->pri_ext = pri_ext;
} else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3)) {
LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
- exit(-1);
+ return ERROR_NOT_IMPLEMENTED;
}
+ return ERROR_OK;
}
diff --git a/src/flash/nor/non_cfi.h b/src/flash/nor/non_cfi.h
index 47d7e59f6..f92ad9d58 100644
--- a/src/flash/nor/non_cfi.h
+++ b/src/flash/nor/non_cfi.h
@@ -20,6 +20,6 @@ struct non_cfi {
uint8_t status_poll_mask;
};
-void cfi_fixup_non_cfi(struct flash_bank *bank);
+int cfi_fixup_non_cfi(struct flash_bank *bank);
#endif /* OPENOCD_FLASH_NOR_NON_CFI_H */
diff --git a/src/flash/nor/str7x.c b/src/flash/nor/str7x.c
index e84721333..121627bab 100644
--- a/src/flash/nor/str7x.c
+++ b/src/flash/nor/str7x.c
@@ -145,7 +145,7 @@ static int str7x_build_block_list(struct flash_bank *bank)
break;
default:
LOG_ERROR("BUG: unknown bank->size encountered");
- exit(-1);
+ return ERROR_FAIL;
}
num_sectors = b0_sectors + b1_sectors;
@@ -197,9 +197,10 @@ FLASH_BANK_COMMAND_HANDLER(str7x_flash_bank_command)
str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0);
str7x_info->disable_bit = (1 << 1);
- if (strcmp(CMD_ARGV[6], "STR71x") == 0)
+ int retval = ERROR_OK;
+ if (strcmp(CMD_ARGV[6], "STR71x") == 0) {
str7x_info->register_base = 0x40100000;
- else if (strcmp(CMD_ARGV[6], "STR73x") == 0) {
+ } else if (strcmp(CMD_ARGV[6], "STR73x") == 0) {
str7x_info->register_base = 0x80100000;
str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA0);
} else if (strcmp(CMD_ARGV[6], "STR75x") == 0) {
@@ -207,13 +208,17 @@ FLASH_BANK_COMMAND_HANDLER(str7x_flash_bank_command)
str7x_info->disable_bit = (1 << 0);
} else {
LOG_ERROR("unknown STR7x variant: '%s'", CMD_ARGV[6]);
- free(str7x_info);
- return ERROR_FLASH_BANK_INVALID;
+ retval = ERROR_FLASH_BANK_INVALID;
}
- str7x_build_block_list(bank);
+ if (retval == ERROR_OK)
+ retval = str7x_build_block_list(bank);
- return ERROR_OK;
+ if (retval != ERROR_OK) {
+ free(bank->driver_priv);
+ bank->driver_priv = NULL;
+ }
+ return retval;
}
/* wait for flash to become idle or report errors.
diff --git a/src/flash/nor/str9x.c b/src/flash/nor/str9x.c
index 9efac241a..2fa0db99d 100644
--- a/src/flash/nor/str9x.c
+++ b/src/flash/nor/str9x.c
@@ -95,7 +95,7 @@ static int str9x_build_block_list(struct flash_bank *bank)
break;
default:
LOG_ERROR("BUG: unknown bank->size encountered");
- exit(-1);
+ return ERROR_FAIL;
}
num_sectors = b0_sectors + b1_sectors;
@@ -142,9 +142,12 @@ FLASH_BANK_COMMAND_HANDLER(str9x_flash_bank_command)
str9x_info = malloc(sizeof(struct str9x_flash_bank));
bank->driver_priv = str9x_info;
- str9x_build_block_list(bank);
-
- return ERROR_OK;
+ int retval = str9x_build_block_list(bank);
+ if (retval != ERROR_OK) {
+ free(bank->driver_priv);
+ bank->driver_priv = NULL;
+ }
+ return retval;
}
static int str9x_protect_check(struct flash_bank *bank)
diff --git a/src/flash/nor/str9xpec.c b/src/flash/nor/str9xpec.c
index b7156a1ae..016f07410 100644
--- a/src/flash/nor/str9xpec.c
+++ b/src/flash/nor/str9xpec.c
@@ -224,7 +224,7 @@ static int str9xpec_build_block_list(struct flash_bank *bank)
break;
default:
LOG_ERROR("BUG: unknown bank->size encountered");
- exit(-1);
+ return ERROR_FAIL;
}
num_sectors = b0_sectors + b1_sectors;
@@ -282,12 +282,16 @@ FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
str9xpec_info->isc_enable = 0;
- str9xpec_build_block_list(bank);
+ int retval = str9xpec_build_block_list(bank);
+ if (retval != ERROR_OK) {
+ free(bank->driver_priv);
+ bank->driver_priv = NULL;
+ }
/* clear option byte register */
buf_set_u32(str9xpec_info->options, 0, 64, 0);
- return ERROR_OK;
+ return retval;
}
static int str9xpec_blank_check(struct flash_bank *bank, unsigned int first,
diff --git a/src/flash/nor/tcl.c b/src/flash/nor/tcl.c
index 57e53dca1..5829d862b 100644
--- a/src/flash/nor/tcl.c
+++ b/src/flash/nor/tcl.c
@@ -606,7 +606,8 @@ COMMAND_HANDLER(handle_flash_fill_command)
break;
default:
LOG_ERROR("BUG: can't happen");
- exit(-1);
+ retval = ERROR_FAIL;
+ goto done;
}
if (padding_at_end) {
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/cfi.c | 4 +++-
src/flash/nor/non_cfi.c | 7 ++++---
src/flash/nor/non_cfi.h | 2 +-
src/flash/nor/str7x.c | 19 ++++++++++++-------
src/flash/nor/str9x.c | 11 +++++++----
src/flash/nor/str9xpec.c | 10 +++++++---
src/flash/nor/tcl.c | 3 ++-
7 files changed, 36 insertions(+), 20 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-13 04:53:43
|
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 bd521b22217b64c47573d084a3ce49a03b1e0e61 (commit)
from b5230e2a0612cd5853b41e557e6d03dd182c83b7 (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 bd521b22217b64c47573d084a3ce49a03b1e0e61
Author: Tomas Vanek <va...@fb...>
Date: Thu Aug 20 10:53:25 2026 +0200
target/riscv: avoid flooding the log during poll
C style guide in chapter "Logging" reads:
"Try to avoid flooding the log with frequently generated messages.
For example, do not use LOG_DEBUG() in operations used for polling
the target. Use LOG_DEBUG_IO() for such frequent messages."
Follow the guide and move the offending debug logs to debug I/O level.
Change-Id: I3e6d71b9182c168648cf60103ae335dab7100d13
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9843
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index a38eed07b..dd5051c1f 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -3868,7 +3868,7 @@ static int riscv_poll_hart(struct target *target, enum riscv_next_action *next_a
{
RISCV_INFO(r);
- LOG_TARGET_DEBUG(target, "polling, target->state=%d", target->state);
+ LOG_TARGET_DEBUG_IO(target, "polling, target->state=%d", target->state);
*next_action = RPH_NONE;
@@ -4045,7 +4045,7 @@ exit:
/*** OpenOCD Interface ***/
int riscv_openocd_poll(struct target *target)
{
- LOG_TARGET_DEBUG(target, "Polling all harts.");
+ LOG_TARGET_DEBUG_IO(target, "Polling all harts.");
struct riscv_info *i = riscv_info(target);
@@ -4104,7 +4104,7 @@ int riscv_openocd_poll(struct target *target)
}
}
- LOG_TARGET_DEBUG(target, "should_remain_halted=%d, should_resume=%d",
+ LOG_TARGET_DEBUG_IO(target, "should_remain_halted=%d, should_resume=%d",
should_remain_halted, should_resume);
if (should_remain_halted && should_resume) {
LOG_TARGET_WARNING(target, "%d harts should remain halted, and %d should resume.",
diff --git a/src/target/riscv/riscv_reg.c b/src/target/riscv/riscv_reg.c
index ba1bc2a85..71d5de280 100644
--- a/src/target/riscv/riscv_reg.c
+++ b/src/target/riscv/riscv_reg.c
@@ -778,7 +778,7 @@ int riscv_reg_flush_all(struct target *target)
if (!target->reg_cache)
return ERROR_OK;
- LOG_TARGET_DEBUG(target, "Flushing register cache");
+ LOG_TARGET_DEBUG_IO(target, "Flushing register cache");
/* Writing non-GPR registers may require progbuf execution, and some GPRs
* may become dirty in the process (e.g. S0, S1). For that reason, flush
@@ -795,7 +795,7 @@ int riscv_reg_flush_all(struct target *target)
return ERROR_FAIL;
}
}
- LOG_TARGET_DEBUG(target, "Flush of register cache completed");
+ LOG_TARGET_DEBUG_IO(target, "Flush of register cache completed");
return ERROR_OK;
}
-----------------------------------------------------------------------
Summary of changes:
src/target/riscv/riscv.c | 6 +++---
src/target/riscv/riscv_reg.c | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-13 04:52: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 b5230e2a0612cd5853b41e557e6d03dd182c83b7 (commit)
from fee41114fc652d6058b8c015db4c659d0464f852 (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 b5230e2a0612cd5853b41e557e6d03dd182c83b7
Author: Tomas Vanek <va...@fb...>
Date: Sat Sep 5 10:08:51 2026 +0200
flash/nor: describe flash driver verify method as optional
While on it refactor flash_driver_verify() not to hide
calling different procedures behind ? : operator.
Use if/else instead. No functional change.
Change-Id: I07d632c2eae53f8aa9ef4cf64ecc592c6a56ae74
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9962
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
index 93c8b7124..34698299b 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -129,8 +129,10 @@ int flash_driver_verify(struct flash_bank *bank,
{
int retval;
- retval = bank->driver->verify ? bank->driver->verify(bank, buffer, offset, count) :
- default_flash_verify(bank, buffer, offset, count);
+ if (bank->driver->verify)
+ retval = bank->driver->verify(bank, buffer, offset, count);
+ else
+ retval = default_flash_verify(bank, buffer, offset, count);
if (retval != ERROR_OK) {
LOG_ERROR("verify failed in bank at " TARGET_ADDR_FMT " starting at 0x%8.8" PRIx32,
bank->base, offset);
diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h
index 48cf2ad36..0d55824e2 100644
--- a/src/flash/nor/driver.h
+++ b/src/flash/nor/driver.h
@@ -149,6 +149,9 @@ struct flash_driver {
* "bank->base + offset", while the physical address is
* dependent upon current target MMU mappings.
*
+ * If the flash does not need device specific verification,
+ * set method to NULL and default_flash_verify() will be used.
+ *
* @param bank The bank to verify
* @param buffer The data bytes to verify against.
* @param offset The offset into the chip to verify.
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/core.c | 6 ++++--
src/flash/nor/driver.h | 3 +++
2 files changed, 7 insertions(+), 2 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-13 04:51:45
|
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 fee41114fc652d6058b8c015db4c659d0464f852 (commit)
from d3e5f5787bea40f5f13c869647deb44b4c051ae0 (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 fee41114fc652d6058b8c015db4c659d0464f852
Author: Tomas Vanek <va...@fb...>
Date: Fri Sep 4 14:43:12 2026 +0200
flash/nor: make free_driver_priv method optional
Currently 62 of 68 flash drivers define
.free_driver_priv = default_free_driver_priv
Fall back to default_free_driver_priv() if the .free_driver_priv
method is NULL
Change-Id: I3e9ab4168a1076823375b671e9fa67ad6bbca29e
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9961
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
index 2c41d1853..93c8b7124 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -221,7 +221,7 @@ void flash_free_all_banks(void)
if (bank->driver->free_driver_priv)
bank->driver->free_driver_priv(bank);
else
- LOG_WARNING("Flash driver of %s does not support free_driver_priv()", bank->name);
+ default_flash_free_driver_priv(bank);
free(bank->sectors);
free(bank->prot_blocks);
diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h
index 6f66f7f0a..48cf2ad36 100644
--- a/src/flash/nor/driver.h
+++ b/src/flash/nor/driver.h
@@ -219,8 +219,12 @@ struct flash_driver {
int (*auto_probe)(struct flash_bank *bank);
/**
- * Deallocates private driver structures.
- * Use default_flash_free_driver_priv() to simply free(bank->driver_priv)
+ * Deallocates private driver structures at exit.
+ *
+ * If the driver does not use driver_priv and keeps it NULL
+ * or allocates just one memory block referenced in driver_priv,
+ * set the method to NULL: default_flash_free_driver_priv() will
+ * simply free(bank->driver_priv) at exit.
*
* @param bank - the bank being destroyed
*/
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/core.c | 2 +-
src/flash/nor/driver.h | 8 ++++++--
2 files changed, 7 insertions(+), 3 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-12 15:41:07
|
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 d3e5f5787bea40f5f13c869647deb44b4c051ae0 (commit)
from 18674aaeb40e644f329285c0927f4abba86a56c5 (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 d3e5f5787bea40f5f13c869647deb44b4c051ae0
Author: Antonio Borneo <bor...@gm...>
Date: Wed Sep 2 23:40:05 2026 +0200
jep106: update to revision JEP106BP September 2026
Update to latest available document.
Change-Id: I197ca03ceb3ef791bac0154305b188a494cb28a3
Signed-off-by: Antonio Borneo <bor...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9952
Tested-by: jenkins
diff --git a/src/helper/jep106.inc b/src/helper/jep106.inc
index a066f0a2e..0643672e9 100644
--- a/src/helper/jep106.inc
+++ b/src/helper/jep106.inc
@@ -8,7 +8,7 @@
* identification code list, please visit the JEDEC website at www.jedec.org .
*/
-/* This file is aligned to revision JEP106BO May 2026. */
+/* This file is aligned to revision JEP106BP September 2026. */
[0][0x01 - 1] = "AMD",
[0][0x02 - 1] = "AMI",
@@ -1400,7 +1400,7 @@
[11][0x02 - 1] = "Semidrive",
[11][0x03 - 1] = "MyTek Electronics Corp",
[11][0x04 - 1] = "Wxilicon Technology Co Ltd",
-[11][0x05 - 1] = "Shenzhen Meixin Electronics Ltd",
+[11][0x05 - 1] = "Shenzhen Chiway Technology Co Ltd",
[11][0x06 - 1] = "Ghost Wolf",
[11][0x07 - 1] = "LiSion Technologies Inc",
[11][0x08 - 1] = "Power Active Co Ltd",
@@ -2081,7 +2081,7 @@
[16][0x35 - 1] = "Shenzhen Shande Semiconductor Co. Ltd.",
[16][0x36 - 1] = "AheadComputing",
[16][0x37 - 1] = "Beijing Ronghua Kangweiye Technology",
-[16][0x38 - 1] = "Shanghai Yunsilicon Technology Co Ltd",
+[16][0x38 - 1] = "Guangdong Long Wins Semiconductor",
[16][0x39 - 1] = "Shenzhen Wolongtai Technology Co Ltd.",
[16][0x3a - 1] = "Vervesemi Microelectronics",
[16][0x3b - 1] = "HRDWYR Ventures Private Limited",
@@ -2114,7 +2114,7 @@
[16][0x56 - 1] = "Shanghai Chip4Tao Technology Co Ltd",
[16][0x57 - 1] = "Shenzhenshijimokkejiyouxiangongsi",
[16][0x58 - 1] = "DEGUA",
-[16][0x59 - 1] = "TENGYIN CELESTIALSTORAGE",
+[16][0x59 - 1] = "Tengyin CelestialStorage",
[16][0x5a - 1] = "Shenzhen Minder Semiconductor Co Ltd",
[16][0x5b - 1] = "GUANGSUJIE",
[16][0x5c - 1] = "HVLANYN Technology",
@@ -2206,10 +2206,114 @@
[17][0x34 - 1] = "ARIA Sensing Srl",
[17][0x35 - 1] = "EverModule Technology Co Ltd",
[17][0x36 - 1] = "The AIO",
-[17][0x37 - 1] = "North Magna Limited",
+[17][0x37 - 1] = "INTEGER",
[17][0x38 - 1] = "Unisemi Power Inc",
[17][0x39 - 1] = "Shenzhen RongPei Technology Co Ltd",
[17][0x3a - 1] = "HKIC International Electronics Limited",
[17][0x3b - 1] = "Shenzhen DTX Space Technology Co Ltd",
[17][0x3c - 1] = "Ranxin Technology",
+[17][0x3d - 1] = "Shenzhen Jinbei Technology Co Ltd",
+[17][0x3e - 1] = "Kubb",
+[17][0x3f - 1] = "Xenith (Shanghai) Technology Co Ltd",
+[17][0x40 - 1] = "Dongguan Xincun Chengbang Technology",
+[17][0x41 - 1] = "Shenzhen Zhuoyun Lianchuang Technology",
+[17][0x42 - 1] = "CS Semiconductor Limited",
+[17][0x43 - 1] = "Fuzhou Huijinshang Electronics Co Ltd",
+[17][0x44 - 1] = "Shenzhen Hangchen Micro Technology Co",
+[17][0x45 - 1] = "Shenzhen EMTEK Storage Technology Co",
+[17][0x46 - 1] = "Wuhan Sifang Chuangxin Technology Co",
+[17][0x47 - 1] = "Shenzhen Lightning Wings Technology Co",
+[17][0x48 - 1] = "Shenzhendaqi Semiconductor Technology",
+[17][0x49 - 1] = "Shenzhen Xinyu Technology Co Ltd",
+[17][0x4a - 1] = "CellByte Technology Co Limited",
+[17][0x4b - 1] = "Nanjing Junji Intelligent Technology Co Ltd",
+[17][0x4c - 1] = "XCENA",
+[17][0x4d - 1] = "Shenzhen Huahao Xin Technology Co",
+[17][0x4e - 1] = "KORX",
+[17][0x4f - 1] = "Beijing Huake Huihai Technology Co Ltd.",
+[17][0x50 - 1] = "Pigvision Microsystems",
+[17][0x51 - 1] = "INPACK Technologies",
+[17][0x52 - 1] = "Dongguan Hongmao Storage Technology",
+[17][0x53 - 1] = "Amitai Group Limited",
+[17][0x54 - 1] = "Shanghai Chuantai Electronic Technology",
+[17][0x55 - 1] = "Shenzhen Xincun Technology Co Ltd",
+[17][0x56 - 1] = "Hyphen Deux Company Limited",
+[17][0x57 - 1] = "Shanghai Huahong ZealCore Electronics",
+[17][0x58 - 1] = "Melexis Technologies NV",
+[17][0x59 - 1] = "BBR",
+[17][0x5a - 1] = "Shenzhen Mainstor Semiconductor",
+[17][0x5b - 1] = "Xin Jiang JIU ZHOU XIAN DA Commercial",
+[17][0x5c - 1] = "Shenzhen Huizhi Lutong Semiconductor",
+[17][0x5d - 1] = "Qingdao Benyuan Microelectronics Co Ltd",
+[17][0x5e - 1] = "Shanghai Puquan Electronic Technology Co",
+[17][0x5f - 1] = "Shanghai RORKE Storage Technology Co",
+[17][0x60 - 1] = "Xiamen SOPHGO Technologies Ltd",
+[17][0x61 - 1] = "Shanghai Fast AI Data Chip Technology Co",
+[17][0x62 - 1] = "Shenzhen Xunlian Semi Co Ltd",
+[17][0x63 - 1] = "Venuchip Technology Co Ltd",
+[17][0x64 - 1] = "Shenzhen Juding Storage Technology Co",
+[17][0x65 - 1] = "Shenzhen RVsilicon Technology Ltd",
+[17][0x66 - 1] = "Geruishi Technology Co Limited",
+[17][0x67 - 1] = "Shenzhen Xinweiling Electronics Co Ltd",
+[17][0x68 - 1] = "Zhaochu Semiconductor (Shenzhen) Co",
+[17][0x69 - 1] = "Nsing Technologies Inc",
+[17][0x6a - 1] = "Communication Technology Ltd",
+[17][0x6b - 1] = "Shenzhen Huachao Electronics Co Ltd",
+[17][0x6c - 1] = "Shenzhen JIN YU Semiconductor Co Ltd",
+[17][0x6d - 1] = "Shenzhen Huanyin Technology Co Ltd",
+[17][0x6e - 1] = "Futurepath Technology (Shenzhen) Co Ltd",
+[17][0x6f - 1] = "Enermade",
+[17][0x70 - 1] = "Shanghai Timar Integrated Circuit Co Ltd",
+[17][0x71 - 1] = "Neo Density Limited",
+[17][0x72 - 1] = "Audinate Holdings Pty Ltd",
+[17][0x73 - 1] = "Beijing Hecun Information Technology Co",
+[17][0x74 - 1] = "Crache Digital International Limited",
+[17][0x75 - 1] = "Suiling (Shenzhen) Intelligent Technology Co",
+[17][0x76 - 1] = "Red Semiconductor International Ltd",
+[17][0x77 - 1] = "Shanghai Saikechi Electronics Co Ltd",
+[17][0x78 - 1] = "Aheesa Digital Innovations Private Limited",
+[17][0x79 - 1] = "Shanghai InfoTM Micro-Electronics Co",
+[17][0x7a - 1] = "Shen Zhen Xin Xi Hao Lin Electronics",
+[17][0x7b - 1] = "Arvern Silicon",
+[17][0x7c - 1] = "MicroSA",
+[17][0x7d - 1] = "Mykybor Electronics Co Limited",
+[17][0x7e - 1] = "Realtek Semiconductor Corporation",
+[18][0x01 - 1] = "SiliconGo Microelectronics Co Ltd SiliconGo",
+[18][0x02 - 1] = "EXRAM",
+[18][0x03 - 1] = "Brillian Network & Automation Integrated",
+[18][0x04 - 1] = "Shenzhen Lingdechuang Technology Co Ltd",
+[18][0x05 - 1] = "UpscalAi",
+[18][0x06 - 1] = "Celero Communications Inc",
+[18][0x07 - 1] = "Umido Technology Co Ltd",
+[18][0x08 - 1] = "Beijing Shi-Xun Electronic Technology Co Ltd",
+[18][0x09 - 1] = "coolpad",
+[18][0x0a - 1] = "Shenzhen Hemingshixian Co Ltd.",
+[18][0x0b - 1] = "Foxin",
+[18][0x0c - 1] = "Shen Zhen Tencen Technology Co Ltd",
+[18][0x0d - 1] = "Calterah Semiconductor Technology",
+[18][0x0e - 1] = "Shenzhen Fushidun Industrial Co Ltd",
+[18][0x0f - 1] = "Shenzhen Annyteck Storage Co Ltd",
+[18][0x10 - 1] = "Xinzexin Holding Co Ltd",
+[18][0x11 - 1] = "tinyGO",
+[18][0x12 - 1] = "Alson Technology Limited",
+[18][0x13 - 1] = "XYXTEM",
+[18][0x14 - 1] = "Mosaic SoC",
+[18][0x15 - 1] = "Micro Computer (HK) Tech Limited",
+[18][0x16 - 1] = "Positron AI Inc",
+[18][0x17 - 1] = "Jogeek Technology Limited",
+[18][0x18 - 1] = "Hunan Jiuren Intelligent Manufacturing",
+[18][0x19 - 1] = "Shenzhen Mensata Cloud AI Technology Co",
+[18][0x1a - 1] = "Weisulang Technology (Shanghai) Co Ltd",
+[18][0x1b - 1] = "Junhangkegong Semiconductor (Shenzhen)",
+[18][0x1c - 1] = "Shenzhen ShengQi Technology Co Ltd",
+[18][0x1d - 1] = "Egis Technology Inc",
+[18][0x1e - 1] = "Nanjing Terra Tech Trade Export Import Co",
+[18][0x1f - 1] = "Shenzhen EAGET Industry Co Ltd",
+[18][0x20 - 1] = "Ibase Technology Inc",
+[18][0x21 - 1] = "Shenzhen Huazi Supercomputing Technology Co",
+[18][0x22 - 1] = "Tokyo Artisan Intelligence",
+[18][0x23 - 1] = "Kiwimoore (Quzhou) Semiconductor Co Ltd",
+[18][0x24 - 1] = "Inspire Semiconductor",
+[18][0x25 - 1] = "Shenzhen Sumem Semiconductor Company",
+[18][0x26 - 1] = "Maiwei Technology Co Ltd",
/* EOF */
-----------------------------------------------------------------------
Summary of changes:
src/helper/jep106.inc | 114 +++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 109 insertions(+), 5 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-12 08:11:19
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 18674aaeb40e644f329285c0927f4abba86a56c5 (commit)
from f3cedea436592b3bff240a412fba58850129334d (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 18674aaeb40e644f329285c0927f4abba86a56c5
Author: Sameer Srivastava <s-s...@ti...>
Date: Sun Mar 8 12:10:37 2026 +0530
tcl: add TI AM13E230X target and LaunchPad configuration
Add Cortex-M33 target configuration defining SRAM work area and flash
regions, plus LaunchPad configuration selecting XDS110 interface at
10000 KHz speed.
Change-Id: I6cb9f52867a1a64895d9ff81f0c38b228578fc1a
Signed-off-by: Sameer Srivastava <s-s...@ti...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9525
Reviewed-by: Tomas Vanek <va...@fb...>
Reviewed-by: Nishanth Menon <nm...@ti...>
Tested-by: jenkins
diff --git a/tcl/board/ti/am13e230x-launchpad.cfg b/tcl/board/ti/am13e230x-launchpad.cfg
new file mode 100644
index 000000000..dd30575f5
--- /dev/null
+++ b/tcl/board/ti/am13e230x-launchpad.cfg
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+#
+
+source [find interface/xds110.cfg]
+
+adapter speed 10000
+transport select jtag
+
+source [find target/ti/am13e230x.cfg]
diff --git a/tcl/target/ti/am13e230x.cfg b/tcl/target/ti/am13e230x.cfg
new file mode 100644
index 000000000..19dd55eb8
--- /dev/null
+++ b/tcl/target/ti/am13e230x.cfg
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+#
+# Texas Instruments AM13E230X - ARM Cortex-M33 @ 200MHz
+#
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME AM13E230X
+}
+
+if { [info exists CPUTAPID] } {
+ set _DAP_TAPID $CPUTAPID
+} else {
+ set _DAP_TAPID 0x6ba00477
+}
+
+if { [info exists DAP_SWD_ID] } {
+ set _DAP_SWD_ID $DAP_SWD_ID
+} else {
+ set _DAP_SWD_ID 0x6ba02477
+}
+
+source [find target/swj-dp.tcl]
+
+swj_newdap $_CHIPNAME cpu -irlen 4 \
+ -expected-id $_DAP_TAPID \
+ -expected-id $_DAP_SWD_ID
+
+dap create $_CHIPNAME.dap -tap $_CHIPNAME.cpu
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap
+
+if { [info exists WORKAREABASE] } {
+ set _WORKAREABASE $WORKAREABASE
+} else {
+ set _WORKAREABASE 0x20000000
+}
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x8000
+}
+
+$_TARGETNAME configure -work-area-phys $_WORKAREABASE -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME.main am13 0x00000000 0 0 0 $_TARGETNAME
+flash bank $_FLASHNAME.nonmain am13 0x60100000 0 0 0 $_TARGETNAME
+
+if {![using_hla]} {
+ # AM13E230X has no SRST pin; use SYSRESETREQ to perform a soft reset.
+ # (HLA adapters issue SYSRESETREQ unconditionally and ignore this setting.)
+ cortex_m reset_config sysresetreq
+}
-----------------------------------------------------------------------
Summary of changes:
tcl/board/ti/am13e230x-launchpad.cfg | 10 +++++++
tcl/target/ti/am13e230x.cfg | 57 ++++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+)
create mode 100644 tcl/board/ti/am13e230x-launchpad.cfg
create mode 100644 tcl/target/ti/am13e230x.cfg
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-12 08:10: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 f3cedea436592b3bff240a412fba58850129334d (commit)
via e975d571bc5ebd703700ef105b11e6d60768a630 (commit)
from 0cc2812da831c57a4cc51f8f2f24de2ad8f324b4 (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 f3cedea436592b3bff240a412fba58850129334d
Author: Sameer Srivastava <s-s...@ti...>
Date: Sun Mar 8 12:15:13 2026 +0530
flash/nor: add am13e230x flash driver
Flashing uses the am13e230x flash loader that runs from SRAM, matching
the CC26xx pattern. The algorithm is loaded into SRAM and started via
target_start_algorithm. OpenOCD streams sector data into two ping-pong
buffers; the algorithm erases each sector and programs it using direct
FCTL register access.
Add AM13 flash driver section in documentation, detailing flash regions,
example commands and the immutability of the first NONMAIN sectors in
each bank.
Change-Id: Ifb910a545146514574fb4efecc3ad5aec38e2576
Signed-off-by: Sameer Srivastava <s-s...@ti...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9527
Reviewed-by: Nishanth Menon <nm...@ti...>
Reviewed-by: Tomas Vanek <va...@fb...>
Tested-by: jenkins
diff --git a/doc/openocd.texi b/doc/openocd.texi
index cb08471be..5e24301e3 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -6840,6 +6840,70 @@ the flash.
@end deffn
@end deffn
+@deffn {Flash Driver} {am13}
+@cindex am13
+@cindex AM13E230X
+All Texas Instruments AM13E230X ARM Cortex-M33 microcontrollers include
+internal flash. The @var{am13} flash driver probes the device by reading
+the JTAGIDCODE (DID) register and the SRAMFLASH info register to
+determine the flash and SRAM sizes automatically.
+
+Two flash regions are supported:
+
+@itemize @bullet
+@item @b{MAIN} flash: starts at address @code{0x00000000}; size is
+auto-detected (typically 256 KB or 512 KB in 2 KB sectors).
+@item @b{NONMAIN} flash: starts at address @code{0x60100000}; sector 0 of each
+bank's NONMAIN region (NM0, at @code{0x60100000} and @code{0x60101000}) is
+BCR-protected and skipped by OpenOCD. The reprogrammable sectors are NM1 of
+each bank (@code{0x60100800} and @code{0x60101800}); size is
+@math{num_banks * 4096} bytes.
+@end itemize
+
+@b{Write strategy}: the driver loads a ping-pong flash loader algorithm
+into SRAM at @code{0x20000000} for fast sector-at-a-time writes. If
+the working area is unavailable (e.g., a RAM-resident application
+occupies SRAM) the driver falls back to slower word-by-word direct
+register writes. The working area @b{must} be configured at
+@code{0x20000000}; this is the default in @file{target/ti/am13e230x.cfg}.
+
+@b{Erase}: performed directly through the NVMNW flash controller
+registers from the debug probe. The GSC flash semaphore is acquired
+before each erase operation and released on completion.
+
+@b{Note}: the flash controller auto-protects after every flash
+operation. OpenOCD automatically un-protects the required sectors
+before each erase or write and does not expose separate protect
+commands.
+
+@b{Example} --- typical @file{flash bank} declarations (already included
+in @file{target/ti/am13e230x.cfg}):
+
+@example
+flash bank $_FLASHNAME.main am13 0x00000000 0 0 0 $_TARGETNAME
+flash bank $_FLASHNAME.nonmain am13 0x60100000 0 0 0 $_TARGETNAME
+@end example
+
+@b{To erase and program MAIN flash}:
+
+@example
+halt
+flash erase_sector 0 0 last
+flash write_image firmware.bin 0x0
+reset run
+@end example
+
+@b{To erase and program NONMAIN flash} (BANK1 NM1, user application storage):
+
+@example
+halt
+flash erase_sector 1 3 3
+flash write_image nonmain.bin 0x60101800
+reset run
+@end example
+
+@end deffn
+
@deffn {Flash Driver} {artery}
@cindex artery
This driver supports Artery Technology devices from the following series:
diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index 66f784126..9a46cc3bc 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -11,6 +11,7 @@ noinst_LTLIBRARIES += %D%/libocdflashnor.la
NOR_DRIVERS = \
%D%/aduc702x.c \
%D%/aducm360.c \
+ %D%/am13e230x.c \
%D%/ambiqmicro.c \
%D%/artery.c \
%D%/at91sam4.c \
diff --git a/src/flash/nor/am13e230x.c b/src/flash/nor/am13e230x.c
new file mode 100644
index 000000000..e44fec739
--- /dev/null
+++ b/src/flash/nor/am13e230x.c
@@ -0,0 +1,758 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * NOR flash driver for AM13E230X class of uC from Texas Instruments.
+ *
+ * Erase uses direct register writes via the debug probe.
+ * Write uses an on-device algorithm loaded into SRAM
+ * (see contrib/loaders/flash/am13e230x/ and flash.h).
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "imp.h"
+#include <helper/binarybuffer.h>
+#include <helper/bits.h>
+#include <helper/time_support.h>
+#include <target/algorithm.h>
+#include <target/armv7m.h>
+
+/* Region memory map */
+#define AM13_FLASH_BASE_MAIN 0x00000000
+#define AM13_FLASH_BASE_NONMAIN 0x60100000
+#define AM13_NONMAIN_SIZE_PER_BANK 0x1000
+
+/*
+ * Factory region registers (at 0x60111000, in the non-main flash area).
+ *
+ * AM13_DID (0x60111004) is the DEVICEID / JTAGIDCODE register ("the
+ * JTAGIDCODE that comes from the Ramp system", per TRM SPRUJF2A Table
+ * 18-1). Its manufacturer ID field lives in bits[11:1] per the JTAG
+ * IEEE 1149.1 encoding, which is what am13_probe() validates.
+ *
+ * This is distinct from PARTIDL/PARTIDH at 0x0005D008, which encode
+ * package type and quality grade. Those fields are not used here
+ * because they vary by package variant and are not needed to confirm
+ * that the target is an AM13E230X-class device.
+ */
+#define AM13_FACTORYREGION 0x60111000
+#define AM13_TRACEID (AM13_FACTORYREGION + 0x000)
+#define AM13_DID (AM13_FACTORYREGION + 0x004) /* JTAGIDCODE */
+#define AM13_SRAMFLASH (AM13_FACTORYREGION + 0x01C)
+
+/* Flash controller (NVMNW) registers */
+#define FLASH_CONTROL_BASE 0x40042000
+#define FCTL_REG_CMDEXEC (FLASH_CONTROL_BASE + 0x1100)
+#define FCTL_REG_CMDTYPE (FLASH_CONTROL_BASE + 0x1104)
+#define FCTL_REG_CMDADDR (FLASH_CONTROL_BASE + 0x1120)
+#define FCTL_REG_CMDBYTEN (FLASH_CONTROL_BASE + 0x1124)
+#define FCTL_REG_CMDDATAINDEX (FLASH_CONTROL_BASE + 0x112C)
+#define FCTL_REG_CMDDATA0 (FLASH_CONTROL_BASE + 0x1130)
+#define FCTL_REG_CMDWEPROTA (FLASH_CONTROL_BASE + 0x11D0)
+#define FCTL_REG_CMDWEPROTB (FLASH_CONTROL_BASE + 0x11D4)
+#define FCTL_REG_CMDWEPROTNM (FLASH_CONTROL_BASE + 0x1210)
+#define FCTL_REG_STATCMD (FLASH_CONTROL_BASE + 0x13D0)
+
+/* GSC flash semaphore registers */
+#define GSC_BASE 0x40046000
+#define GSC_REG_FPC_FLSEMREQ (GSC_BASE + 0x1800)
+#define GSC_REG_FPC_FLSEMCLR (GSC_BASE + 0x1804)
+
+/* STATCMD bits */
+#define FCTL_STATCMD_CMDDONE 0x00000001
+#define FCTL_STATCMD_CMDPASS 0x00000002
+#define FCTL_STATCMD_CMDINPROGRESS 0x00000004
+
+/* CMDEXEC / CMDTYPE constants */
+#define FCTL_CMDEXEC_EXECUTE 0x00000001
+#define FCTL_CMDTYPE_PROGRAM 0x00000001
+#define FCTL_CMDTYPE_ERASE 0x00000002
+#define FCTL_CMDTYPE_CLEARSTATUS 0x00000005
+#define FCTL_CMDTYPE_SIZE_ONEWORD 0x00000000
+#define FCTL_CMDTYPE_SIZE_SECTOR 0x00000040
+
+#define AM13_FLASH_WORD_SIZE 16
+
+#define AM13_FLASH_TIMEOUT_MS 8000
+#define AM13_SECTOR_SIZE_BYTES 0x800
+#define TI_MANUFACTURER_ID 0x17
+
+/* Algorithm is loaded at the base of SRAM */
+#define AM13_ALGO_BASE 0x20000000
+
+/* Parameter blocks (two, for ping-pong) */
+#define AM13_ALGO_PARAMS_0 0x20002000
+#define AM13_ALGO_PARAMS_1 0x20002014
+
+/* Data buffers (each one sector = 2 KB) */
+#define AM13_ALGO_BUFFER_0 0x20002100
+#define AM13_ALGO_BUFFER_1 0x20002900
+
+/* Total working area needed */
+#define AM13_ALGO_WORKING_SIZE (AM13_ALGO_BUFFER_1 + 0x800 - AM13_ALGO_BASE)
+
+/* Handshake values (must match loader main.c) */
+#define AM13_BUFFER_EMPTY 0x00000000
+#define AM13_BUFFER_FULL 0xFFFFFFFF
+
+/* Offset of the status field within flash_params */
+#define AM13_STATUS_OFFSET 0x0C
+
+/* Commands (must match loader main.c) */
+#define AM13_CMD_NO_ACTION 0
+#define AM13_CMD_PROGRAM 1
+#define AM13_CMD_ERASE_AND_PROGRAM 2
+#define AM13_CMD_ERASE_SECTORS 3
+
+/* Parameter block layout (matches struct flash_params in loader) */
+struct am13_algo_params {
+ uint8_t dest[4];
+ uint8_t len[4];
+ uint8_t cmd[4];
+ uint8_t status[4];
+ uint8_t buf_addr[4];
+};
+
+/* Flash loader algorithm binary */
+static const uint8_t am13_algo[] = {
+#include "../../../contrib/loaders/flash/am13e230x/am13e230x_algo.inc"
+};
+
+struct am13_flash_bank {
+ uint32_t did;
+ uint32_t traceid;
+ unsigned int main_flash_size_kb;
+ unsigned int main_flash_num_banks;
+ unsigned int sram_size_kb;
+ unsigned int sector_size;
+
+ /* Algorithm state */
+ struct working_area *working_area;
+ struct armv7m_algorithm armv7m_info;
+};
+
+static int am13_auto_probe(struct flash_bank *bank);
+
+/*
+ * GSC flash semaphore must be held before any flash operation.
+ * The debug probe and the CPU have separate ownership tracking
+ * (FLSEMSTAT.DBGACC), so the erase path (debug probe) and the
+ * write path (on-device algorithm) each acquire it independently.
+ */
+
+static int am13_request_gsc_semaphore(struct flash_bank *bank)
+{
+ int retval = target_write_u32(bank->target, GSC_REG_FPC_FLSEMREQ, 1);
+ if (retval != ERROR_OK)
+ LOG_ERROR("AM13: failed to acquire GSC flash semaphore");
+ return retval;
+}
+
+static int am13_clear_gsc_semaphore(struct flash_bank *bank)
+{
+ int retval = target_write_u32(bank->target, GSC_REG_FPC_FLSEMCLR, 1);
+ if (retval != ERROR_OK)
+ LOG_ERROR("AM13: failed to release GSC flash semaphore");
+ return retval;
+}
+
+/* ---------- Flash controller helpers (erase path only) ---------- */
+
+static const struct {
+ unsigned char bit;
+ const char *name;
+} am13_fctl_errors[] = {
+ { 2, "CMDINPROGRESS" },
+ { 4, "FAILWEPROT" },
+ { 5, "FAILVERIFY" },
+ { 6, "FAILILLADDR" },
+ { 7, "FAILMODE" },
+ { 12, "FAILMISC" },
+};
+
+static const char *am13_fctl_strerror(uint32_t status)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(am13_fctl_errors); i++) {
+ if (status & BIT(am13_fctl_errors[i].bit))
+ return am13_fctl_errors[i].name;
+ }
+ return "FAILUNKNOWN";
+}
+
+static int am13_fctl_wait_done(struct flash_bank *bank)
+{
+ struct target *target = bank->target;
+ uint32_t status = 0;
+ int64_t start_ms = timeval_ms();
+ bool timed_out = false;
+
+ while ((status & FCTL_STATCMD_CMDDONE) == 0) {
+ int retval = target_read_u32(target, FCTL_REG_STATCMD, &status);
+ if (retval != ERROR_OK)
+ return retval;
+ if (timeval_ms() - start_ms > AM13_FLASH_TIMEOUT_MS) {
+ timed_out = true;
+ break;
+ }
+ keep_alive();
+ }
+
+ if ((status & FCTL_STATCMD_CMDPASS) == 0) {
+ if (timed_out)
+ LOG_ERROR("AM13: flash command timed out after %d ms", AM13_FLASH_TIMEOUT_MS);
+ else
+ LOG_ERROR("AM13: flash command failed: %s", am13_fctl_strerror(status));
+ return ERROR_FAIL;
+ }
+
+ return ERROR_OK;
+}
+
+static int am13_fctl_clear_status(struct flash_bank *bank)
+{
+ struct target *target = bank->target;
+ uint32_t status;
+ int64_t start_ms;
+ int retval;
+
+ retval = target_write_u32(target, FCTL_REG_CMDTYPE, FCTL_CMDTYPE_CLEARSTATUS);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(target, FCTL_REG_CMDEXEC, FCTL_CMDEXEC_EXECUTE);
+ if (retval != ERROR_OK)
+ return retval;
+
+ start_ms = timeval_ms();
+ do {
+ retval = target_read_u32(target, FCTL_REG_STATCMD, &status);
+ if (retval != ERROR_OK)
+ return retval;
+ if (timeval_ms() - start_ms > AM13_FLASH_TIMEOUT_MS) {
+ LOG_ERROR("Timeout waiting for clear status");
+ return ERROR_FAIL;
+ }
+ keep_alive();
+ } while (status & FCTL_STATCMD_CMDINPROGRESS);
+
+ return ERROR_OK;
+}
+
+static int am13_fctl_unprotect(struct flash_bank *bank)
+{
+ struct target *target = bank->target;
+ int retval;
+
+ switch (bank->base) {
+ case AM13_FLASH_BASE_MAIN:
+ retval = target_write_u32(target, FCTL_REG_CMDWEPROTA, 0);
+ if (retval != ERROR_OK)
+ return retval;
+ return target_write_u32(target, FCTL_REG_CMDWEPROTB, 0);
+ case AM13_FLASH_BASE_NONMAIN:
+ return target_write_u32(target, FCTL_REG_CMDWEPROTNM, 0);
+ default:
+ return ERROR_FLASH_BANK_INVALID;
+ }
+}
+
+static int am13_fctl_erase(struct flash_bank *bank, uint32_t addr, uint32_t cmd_size)
+{
+ struct target *target = bank->target;
+ int retval;
+
+ retval = am13_fctl_clear_status(bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = am13_fctl_unprotect(bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(target, FCTL_REG_CMDTYPE,
+ FCTL_CMDTYPE_ERASE | cmd_size);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(target, FCTL_REG_CMDADDR, addr & 0xFFFFFFF0);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(target, FCTL_REG_CMDEXEC, FCTL_CMDEXEC_EXECUTE);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return am13_fctl_wait_done(bank);
+}
+
+/* ---------- Flash driver callbacks ---------- */
+
+FLASH_BANK_COMMAND_HANDLER(am13_flash_bank_command)
+{
+ switch (bank->base) {
+ case AM13_FLASH_BASE_MAIN:
+ case AM13_FLASH_BASE_NONMAIN:
+ break;
+ default:
+ LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FAIL;
+ }
+
+ struct am13_flash_bank *am13_info = calloc(1, sizeof(*am13_info));
+ if (!am13_info)
+ return ERROR_FAIL;
+
+ bank->driver_priv = am13_info;
+ am13_info->sector_size = AM13_SECTOR_SIZE_BYTES;
+
+ bank->write_start_alignment = AM13_FLASH_WORD_SIZE;
+ bank->write_end_alignment = AM13_FLASH_WORD_SIZE;
+
+ return ERROR_OK;
+}
+
+static int am13_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
+{
+ struct am13_flash_bank *am13_info = bank->driver_priv;
+ int retval;
+
+ if (bank->target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ retval = am13_request_gsc_semaphore(bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ for (unsigned int s = first; s <= last; s++) {
+ if (bank->sectors[s].is_protected) {
+ LOG_WARNING("AM13: NONMAIN sector %u (0x%08" TARGET_PRIxADDR
+ ") is factory-protected, skipping",
+ s, bank->base + s * am13_info->sector_size);
+ continue;
+ }
+
+ uint32_t addr = bank->base + s * am13_info->sector_size;
+
+ retval = am13_fctl_erase(bank, addr, FCTL_CMDTYPE_SIZE_SECTOR);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("AM13: Sector erase failed at 0x%08" PRIx32 ", returned %d", addr, retval);
+ am13_clear_gsc_semaphore(bank);
+ return retval;
+ }
+ }
+
+ return am13_clear_gsc_semaphore(bank);
+}
+
+/* ---------- Direct write fallback (via debug probe) ---------- */
+
+/*
+ * Word-by-word flash write using direct register access from the debug
+ * probe. Slower than the on-device algorithm but does not require SRAM,
+ * so it works as a fallback when the algorithm cannot be loaded (e.g.,
+ * SRAM is needed by a RAM-resident application).
+ */
+static int am13_write_direct(struct flash_bank *bank, const uint8_t *buffer,
+ uint32_t offset, uint32_t count)
+{
+ if (count == 0)
+ return ERROR_OK;
+
+ struct target *target = bank->target;
+ uint32_t addr = bank->base + offset;
+ int retval = 0;
+
+ retval = am13_request_gsc_semaphore(bank);
+ if (retval != ERROR_OK)
+ return retval;
+
+ while (count > 0) {
+ /* Clear status + unprotect before every word (per SDK) */
+ retval = am13_fctl_clear_status(bank);
+ if (retval != ERROR_OK)
+ break;
+
+ retval = am13_fctl_unprotect(bank);
+ if (retval != ERROR_OK)
+ break;
+
+ retval = target_write_u32(target, FCTL_REG_CMDTYPE,
+ FCTL_CMDTYPE_PROGRAM | FCTL_CMDTYPE_SIZE_ONEWORD);
+ if (retval != ERROR_OK)
+ break;
+
+ /* All 16 data bytes + both ECC chunks (bits 16-17) enabled */
+ retval = target_write_u32(target, FCTL_REG_CMDBYTEN, 0x0003FFFF);
+ if (retval != ERROR_OK)
+ break;
+
+ retval = target_write_u32(target, FCTL_REG_CMDADDR, addr);
+ if (retval != ERROR_OK)
+ break;
+
+ retval = target_write_u32(target, FCTL_REG_CMDDATAINDEX,
+ (addr >> 4) & 3);
+ if (retval != ERROR_OK)
+ break;
+
+ retval = target_write_buffer(target, FCTL_REG_CMDDATA0, AM13_FLASH_WORD_SIZE, buffer);
+ if (retval != ERROR_OK)
+ break;
+
+ retval = target_write_u32(target, FCTL_REG_CMDEXEC,
+ FCTL_CMDEXEC_EXECUTE);
+ if (retval != ERROR_OK)
+ break;
+
+ retval = am13_fctl_wait_done(bank);
+ if (retval != ERROR_OK)
+ break;
+
+ addr += AM13_FLASH_WORD_SIZE;
+ buffer += AM13_FLASH_WORD_SIZE;
+ count -= AM13_FLASH_WORD_SIZE;
+ }
+
+ int sem_ret = am13_clear_gsc_semaphore(bank);
+ return (retval != ERROR_OK) ? retval : sem_ret;
+}
+
+/* ---------- Flash loader algorithm ---------- */
+
+static int am13_algo_init(struct flash_bank *bank)
+{
+ struct target *target = bank->target;
+ struct am13_flash_bank *am13_info = bank->driver_priv;
+ int retval;
+
+ /* Allocate SRAM for algorithm + buffers */
+ target_free_working_area(target, am13_info->working_area);
+ am13_info->working_area = NULL;
+
+ retval = target_alloc_working_area(target, AM13_ALGO_WORKING_SIZE,
+ &am13_info->working_area);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("AM13: insufficient SRAM for flash loader (%u bytes)",
+ AM13_ALGO_WORKING_SIZE);
+ return retval;
+ }
+
+ /*
+ * The flash loader is not position-independent: it references
+ * parameter blocks (AM13_ALGO_PARAMS_0/1) and data buffers
+ * (AM13_ALGO_BUFFER_0/1) at absolute SRAM addresses assembled
+ * into the binary. The working area must start exactly at
+ * AM13_ALGO_BASE (0x20000000).
+ */
+ if (am13_info->working_area->address != AM13_ALGO_BASE) {
+ LOG_ERROR("AM13: working area allocated at 0x%08" TARGET_PRIxADDR
+ ", need 0x%08x; set '_WORKAREABASE 0x%08x' in target config",
+ am13_info->working_area->address,
+ AM13_ALGO_BASE, AM13_ALGO_BASE);
+ target_free_working_area(target, am13_info->working_area);
+ am13_info->working_area = NULL;
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
+ retval = target_write_buffer(target, AM13_ALGO_BASE, sizeof(am13_algo), am13_algo);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("AM13: failed to load flash algorithm");
+ target_free_working_area(target, am13_info->working_area);
+ am13_info->working_area = NULL;
+ return retval;
+ }
+
+ /*
+ * Release any debug-held GSC semaphore so the algorithm (CPU)
+ * can acquire it â the flash controller tracks ownership via
+ * FLSEMSTAT.DBGACC and rejects mismatched access.
+ */
+ retval = am13_clear_gsc_semaphore(bank);
+ if (retval != ERROR_OK) {
+ target_free_working_area(target, am13_info->working_area);
+ am13_info->working_area = NULL;
+ return retval;
+ }
+
+ am13_info->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ am13_info->armv7m_info.core_mode = ARM_MODE_THREAD;
+
+ LOG_DEBUG("AM13: starting flash algorithm");
+ retval = target_start_algorithm(target, 0, NULL, 0, NULL,
+ AM13_ALGO_BASE, 0,
+ &am13_info->armv7m_info);
+
+ if (retval != ERROR_OK) {
+ LOG_ERROR("AM13: failed to start flash algorithm");
+ goto err_free_working_area;
+ }
+
+ return ERROR_OK;
+
+err_free_working_area:
+ target_free_working_area(target, am13_info->working_area);
+ am13_info->working_area = NULL;
+ return retval;
+}
+
+static int am13_algo_quit(struct flash_bank *bank)
+{
+ struct target *target = bank->target;
+ struct am13_flash_bank *am13_info = bank->driver_priv;
+
+ (void)target_halt(target);
+
+ int retval = target_wait_algorithm(target, 0, NULL, 0, NULL,
+ 0, AM13_FLASH_TIMEOUT_MS,
+ &am13_info->armv7m_info);
+
+ int sem_ret = am13_clear_gsc_semaphore(bank);
+
+ target_free_working_area(target, am13_info->working_area);
+ am13_info->working_area = NULL;
+
+ return (retval != ERROR_OK) ? retval : sem_ret;
+}
+
+static int am13_algo_wait_done(struct flash_bank *bank, uint32_t params_addr)
+{
+ struct target *target = bank->target;
+ uint32_t status = AM13_BUFFER_FULL;
+ int64_t start_ms = timeval_ms();
+ int retval;
+ bool timed_out = false;
+
+ while (status == AM13_BUFFER_FULL) {
+ retval = target_read_u32(target, params_addr + AM13_STATUS_OFFSET,
+ &status);
+ if (retval != ERROR_OK)
+ return retval;
+
+ int64_t elapsed_ms = timeval_ms() - start_ms;
+ if (elapsed_ms > 500)
+ keep_alive();
+ if (elapsed_ms > AM13_FLASH_TIMEOUT_MS) {
+ timed_out = true;
+ break;
+ }
+ }
+
+ if (timed_out) {
+ LOG_ERROR("AM13: flash algorithm timed out after %d ms", AM13_FLASH_TIMEOUT_MS);
+ return ERROR_FAIL;
+ }
+
+ if (status != AM13_BUFFER_EMPTY) {
+ LOG_ERROR("AM13: flash algorithm error, status=0x%08" PRIx32,
+ status);
+ return ERROR_FAIL;
+ }
+
+ return ERROR_OK;
+}
+
+static int am13_write(struct flash_bank *bank, const uint8_t *buffer,
+ uint32_t offset, uint32_t count)
+{
+ struct target *target = bank->target;
+ struct am13_algo_params algo_params[2];
+ int retval;
+
+ if (target->state != TARGET_HALTED) {
+ LOG_ERROR("Target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ retval = am13_algo_init(bank);
+ if (retval != ERROR_OK) {
+ LOG_INFO("AM13: algorithm unavailable, falling back to direct writes");
+ return am13_write_direct(bank, buffer, offset, count);
+ }
+
+ static const uint32_t params_addr[] = {
+ AM13_ALGO_PARAMS_0, AM13_ALGO_PARAMS_1
+ };
+ static const uint32_t buffer_addr[] = {
+ AM13_ALGO_BUFFER_0, AM13_ALGO_BUFFER_1
+ };
+
+ uint32_t address = bank->base + offset;
+ uint32_t index = 0;
+ int64_t start_ms = timeval_ms();
+
+ buf_set_u32(algo_params[0].cmd, 0, 32, AM13_CMD_PROGRAM);
+ buf_set_u32(algo_params[1].cmd, 0, 32, AM13_CMD_PROGRAM);
+
+ while (count > 0) {
+ uint32_t size = MIN(count, AM13_SECTOR_SIZE_BYTES - (address % AM13_SECTOR_SIZE_BYTES));
+
+ retval = target_write_buffer(target, buffer_addr[index], size, buffer);
+ if (retval != ERROR_OK)
+ break;
+
+ buf_set_u32(algo_params[index].dest, 0, 32, address);
+ buf_set_u32(algo_params[index].len, 0, 32, size);
+ buf_set_u32(algo_params[index].status, 0, 32, AM13_BUFFER_FULL);
+
+ /* Write dest/len/cmd/status only â preserve algorithm's buf_addr */
+ retval = target_write_buffer(target, params_addr[index],
+ offsetof(struct am13_algo_params, buf_addr),
+ (uint8_t *)&algo_params[index]);
+ if (retval != ERROR_OK)
+ break;
+
+ index ^= 1;
+ retval = am13_algo_wait_done(bank, params_addr[index]);
+ if (retval != ERROR_OK)
+ break;
+
+ count -= size;
+ buffer += size;
+ address += size;
+
+ if (timeval_ms() - start_ms > 500)
+ keep_alive();
+ }
+
+ /* Wait for the last submitted buffer */
+ if (retval == ERROR_OK) {
+ index ^= 1;
+ retval = am13_algo_wait_done(bank, params_addr[index]);
+ }
+
+ int quit_ret = am13_algo_quit(bank);
+ return (retval != ERROR_OK) ? retval : quit_ret;
+}
+
+/* ---------- Probe ---------- */
+
+static int am13_probe(struct flash_bank *bank)
+{
+ struct target *target = bank->target;
+ struct am13_flash_bank *am13_info = bank->driver_priv;
+ uint32_t did, sramflash;
+ int retval;
+
+ retval = target_read_u32(target, AM13_DID, &did);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (((did & GENMASK(11, 1)) >> 1) != TI_MANUFACTURER_ID) {
+ LOG_ERROR("AM13: unexpected manufacturer ID in DID=0x%08" PRIx32,
+ did);
+ return ERROR_FAIL;
+ }
+
+ am13_info->did = did;
+
+ retval = target_read_u32(target, AM13_TRACEID, &am13_info->traceid);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_u32(target, AM13_SRAMFLASH, &sramflash);
+ if (retval != ERROR_OK)
+ return retval;
+
+ am13_info->main_flash_size_kb = sramflash & GENMASK(11, 0);
+ am13_info->main_flash_num_banks = (sramflash & GENMASK(13, 12)) >> 12;
+ am13_info->sram_size_kb = (sramflash & GENMASK(25, 16)) >> 16;
+
+ free(bank->sectors);
+ bank->sectors = NULL;
+
+ unsigned int num_sectors;
+ switch (bank->base) {
+ case AM13_FLASH_BASE_MAIN:
+ bank->size = am13_info->main_flash_size_kb * 1024;
+ num_sectors = bank->size / am13_info->sector_size;
+ break;
+ case AM13_FLASH_BASE_NONMAIN:
+ bank->size = am13_info->main_flash_num_banks * AM13_NONMAIN_SIZE_PER_BANK;
+ num_sectors = bank->size / am13_info->sector_size;
+ break;
+ default:
+ LOG_ERROR("Invalid bank address " TARGET_ADDR_FMT, bank->base);
+ return ERROR_FAIL;
+ }
+
+ if (num_sectors == 0) {
+ bank->num_sectors = 0;
+ bank->size = 0;
+ return ERROR_OK;
+ }
+
+ bank->num_sectors = num_sectors;
+ bank->sectors = calloc(num_sectors, sizeof(struct flash_sector));
+ if (!bank->sectors)
+ return ERROR_FAIL;
+
+ /*
+ * NONMAIN sector 0 of each bank contains factory trim and boot
+ * configuration records that are hardware-permanently protected.
+ * The NVMNW returns FAILILLADDR for any erase attempt on them.
+ */
+ unsigned int sectors_per_nm_bank =
+ (bank->base == AM13_FLASH_BASE_NONMAIN)
+ ? AM13_NONMAIN_SIZE_PER_BANK / am13_info->sector_size
+ : 0;
+
+ for (unsigned int i = 0; i < num_sectors; i++) {
+ bank->sectors[i].offset = i * am13_info->sector_size;
+ bank->sectors[i].size = am13_info->sector_size;
+ bank->sectors[i].is_erased = -1;
+ bank->sectors[i].is_protected =
+ (sectors_per_nm_bank && (i % sectors_per_nm_bank) == 0) ? 1 : 0;
+ }
+
+ LOG_INFO("AM13: %s flash: %u KB (%u sectors), %u bank(s), SRAM: %u KB",
+ (bank->base == AM13_FLASH_BASE_MAIN) ? "MAIN" : "NONMAIN",
+ (unsigned int)(bank->size / 1024), num_sectors,
+ am13_info->main_flash_num_banks,
+ am13_info->sram_size_kb);
+
+ return ERROR_OK;
+}
+
+static int am13_auto_probe(struct flash_bank *bank)
+{
+ struct am13_flash_bank *am13_info = bank->driver_priv;
+
+ if (am13_info->did)
+ return ERROR_OK;
+
+ return am13_probe(bank);
+}
+
+static int get_am13_info(struct flash_bank *bank,
+ struct command_invocation *cmd)
+{
+ struct am13_flash_bank *am13_info = bank->driver_priv;
+
+ command_print_sameline(cmd, "AM13E23X: DID=0x%08" PRIx32
+ " TRACEID=0x%08" PRIx32
+ " banks=%u",
+ am13_info->did, am13_info->traceid,
+ am13_info->main_flash_num_banks);
+ return ERROR_OK;
+}
+
+const struct flash_driver am13_flash = {
+ .name = "am13",
+ .flash_bank_command = am13_flash_bank_command,
+ .erase = am13_erase,
+ .protect = NULL,
+ .write = am13_write,
+ .read = default_flash_read,
+ .probe = am13_probe,
+ .auto_probe = am13_auto_probe,
+ .erase_check = default_flash_blank_check,
+ .protect_check = NULL,
+ .info = get_am13_info,
+ .free_driver_priv = default_flash_free_driver_priv,
+};
diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h
index 36bba50b3..6f66f7f0a 100644
--- a/src/flash/nor/driver.h
+++ b/src/flash/nor/driver.h
@@ -240,6 +240,7 @@ const struct flash_driver *flash_driver_find_by_name(const char *name);
// Keep in alphabetic order this list of drivers
extern const struct flash_driver aduc702x_flash;
extern const struct flash_driver aducm360_flash;
+extern const struct flash_driver am13_flash;
extern const struct flash_driver ambiqmicro_flash;
extern const struct flash_driver artery_flash;
extern const struct flash_driver at91sam3_flash;
diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c
index 03d829da6..2183c4c96 100644
--- a/src/flash/nor/drivers.c
+++ b/src/flash/nor/drivers.c
@@ -19,6 +19,7 @@ static const struct flash_driver * const flash_drivers[] = {
// Keep in alphabetic order the list of drivers
&aduc702x_flash,
&aducm360_flash,
+ &am13_flash,
&ambiqmicro_flash,
&artery_flash,
&at91sam3_flash,
commit e975d571bc5ebd703700ef105b11e6d60768a630
Author: Sameer Srivastava <s-s...@ti...>
Date: Sun Mar 8 12:12:04 2026 +0530
contrib/loaders/flash/am13e230x: add flash loader algorithm
Add a flash loader for AM13E230X that receives flash sectors via shared
memory ping-pong buffers, similar to the CC26xx flash loader.
The flash loader am13e230x_algo.inc was built with the Arm GNU Toolchain
15.2.1 20251203.
Change-Id: If5759b6f513cf94a0208d1bf4e95eb012a297d17
Signed-off-by: Sameer Srivastava <s-s...@ti...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9526
Tested-by: jenkins
Reviewed-by: Nishanth Menon <nm...@ti...>
Reviewed-by: Tomas Vanek <va...@fb...>
diff --git a/contrib/loaders/flash/am13e230x/Makefile b/contrib/loaders/flash/am13e230x/Makefile
new file mode 100644
index 000000000..689e4cdf8
--- /dev/null
+++ b/contrib/loaders/flash/am13e230x/Makefile
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+
+BIN2C = ../../../../src/helper/bin2char.sh
+
+CROSS_COMPILE ?= arm-none-eabi-
+GCC = $(CROSS_COMPILE)gcc
+OBJCOPY = $(CROSS_COMPILE)objcopy
+
+FLAGS = -mcpu=cortex-m33 -mthumb -Os
+FLAGS += -ffunction-sections -fdata-sections
+FLAGS += -g -gdwarf-3 -gstrict-dwarf
+FLAGS += -Wall -fno-strict-aliasing -fno-builtin
+FLAGS += -nostdlib -nostartfiles
+
+CFLAGS = -c -I.
+
+OBJS := \
+ startup.o \
+ main.o \
+ flash.o
+
+all: am13e230x_algo.inc
+
+%.o: %.c
+ @echo 'Building: $<'
+ $(GCC) $(FLAGS) $(CFLAGS) -o "$@" "$<"
+
+am13e230x_algo.out: $(OBJS)
+ @echo 'Linking: $@'
+ $(GCC) $(FLAGS) -o $@ $(OBJS) -Wl,-T"am13e230x.lds"
+
+%.bin: %.out
+ @echo 'Objcopy: $@'
+ $(OBJCOPY) -Obinary $< $@
+
+%.inc: %.bin
+ @echo 'Bin2Char: $@'
+ $(BIN2C) < $< > $@
+ rm $< $*.out
+
+clean:
+ rm -rf *.o *.d *.out *.bin *.inc *.map
+
+.PRECIOUS: %.bin
+
+.PHONY: all clean
diff --git a/contrib/loaders/flash/am13e230x/am13e230x.lds b/contrib/loaders/flash/am13e230x/am13e230x.lds
new file mode 100644
index 000000000..01240c11b
--- /dev/null
+++ b/contrib/loaders/flash/am13e230x/am13e230x.lds
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/******************************************************************************
+ *
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Linker script for AM13E230X flash loader algorithm.
+ * Everything runs from SRAM. Params and buffers are at fixed addresses
+ * that the OpenOCD driver knows about (see flash.h).
+ *
+ *****************************************************************************/
+
+ENTRY( entry )
+
+MEMORY
+{
+ /* Code, data, bss, stack */
+ PROGRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x2000
+ /* Params and data buffers at known addresses */
+ BUFFERS (RWX) : ORIGIN = 0x20002000, LENGTH = 0x1100
+}
+
+SECTIONS
+{
+ .text :
+ {
+ _text = .;
+ *(.entry*)
+ *(.text*)
+ _etext = .;
+ } > PROGRAM
+
+ .data :
+ {
+ _data = .;
+ *(.rodata*)
+ *(.data*)
+ _edata = .;
+ } > PROGRAM
+
+ .bss (NOLOAD) :
+ {
+ __bss_start__ = .;
+ _bss = .;
+ *(.bss*)
+ *(COMMON)
+ _ebss = .;
+ __bss_end__ = .;
+ } > PROGRAM
+
+ .stack (NOLOAD) :
+ {
+ _stack = .;
+ *(.stack*)
+ _estack = .;
+ } > PROGRAM
+
+ .buffers (NOLOAD) :
+ {
+ _buffers = .;
+ *(.buffers.params)
+ . = 0x100;
+ *(.buffers.buf0)
+ *(.buffers.buf1)
+ _ebuffers = .;
+ } > BUFFERS
+}
diff --git a/contrib/loaders/flash/am13e230x/am13e230x_algo.inc b/contrib/loaders/flash/am13e230x/am13e230x_algo.inc
new file mode 100644
index 000000000..30f710f04
--- /dev/null
+++ b/contrib/loaders/flash/am13e230x/am13e230x_algo.inc
@@ -0,0 +1,49 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0x4f,0xf0,0x00,0x00,0x80,0xf3,0x14,0x88,0xbf,0xf3,0x6f,0x8f,0xdf,0xf8,0x18,0xd0,
+0x06,0x48,0x07,0x49,0x4f,0xf0,0x00,0x02,0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,
+0xfa,0xdb,0x00,0xf0,0x07,0xf8,0xfe,0xe7,0x88,0x04,0x00,0x20,0xf8,0x02,0x00,0x20,
+0xf8,0x02,0x00,0x20,0x2d,0xe9,0xf8,0x43,0x00,0x25,0x41,0x4c,0x41,0x4b,0x23,0x61,
+0x41,0x4b,0x63,0x62,0x23,0x7b,0x25,0x73,0x63,0x7b,0x65,0x73,0xa3,0x7b,0xa5,0x73,
+0xe3,0x7b,0xe5,0x73,0x94,0xf8,0x20,0x30,0x84,0xf8,0x20,0x50,0x94,0xf8,0x21,0x30,
+0x84,0xf8,0x21,0x50,0x94,0xf8,0x22,0x30,0x84,0xf8,0x22,0x50,0x94,0xf8,0x23,0x30,
+0x84,0xf8,0x23,0x50,0x00,0xf0,0xac,0xf8,0x50,0xb1,0x23,0x7b,0x04,0x23,0x23,0x73,
+0x63,0x7b,0x01,0x23,0x63,0x73,0xa3,0x7b,0xa5,0x73,0xe3,0x7b,0xe5,0x73,0xfe,0xe7,
+0x05,0x46,0x4f,0xf0,0x14,0x09,0x80,0x46,0x09,0xfb,0x05,0xf6,0xa7,0x19,0x07,0xf1,
+0x08,0x02,0x53,0x68,0x00,0x2b,0xfc,0xd0,0xbb,0x68,0x02,0x2b,0x19,0xd0,0x03,0x2b,
+0x24,0xd0,0x01,0x2b,0x19,0xd0,0x40,0xf2,0x03,0x12,0x14,0x23,0x03,0xfb,0x05,0x44,
+0xe2,0x60,0x08,0x34,0x00,0xf0,0x9c,0xf8,0x50,0xb1,0x05,0x22,0x23,0x79,0x22,0x71,
+0x62,0x79,0x01,0x22,0x00,0x23,0x62,0x71,0xa2,0x79,0xa3,0x71,0xe2,0x79,0xe3,0x71,
+0xfe,0xe7,0xa0,0x59,0x00,0xf0,0x9a,0xf8,0x68,0xb9,0x38,0x69,0xa1,0x59,0x7a,0x68,
+0x00,0xf0,0xb0,0xf8,0x98,0xb1,0x4f,0xf4,0x81,0x72,0xde,0xe7,0xa6,0x59,0x7b,0x68,
+0xf2,0x18,0x17,0x46,0x09,0xd3,0x40,0xf2,0x01,0x12,0xd6,0xe7,0x30,0x46,0x00,0xf0,
+0x85,0xf8,0x00,0x28,0xf7,0xd1,0x06,0xf5,0x00,0x66,0xb7,0x42,0xf6,0xd8,0x09,0xfb,
+0x05,0x43,0x1a,0x7b,0x83,0xf8,0x0c,0x80,0x5a,0x7b,0x83,0xf8,0x0d,0x80,0x9a,0x7b,
+0x83,0xf8,0x0e,0x80,0xda,0x7b,0x85,0xf0,0x01,0x05,0x83,0xf8,0x0f,0x80,0xab,0xe7,
+0x00,0x20,0x00,0x20,0x00,0x21,0x00,0x20,0x00,0x29,0x00,0x20,0xfe,0xe7,0x00,0x00,
+0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x01,0x23,0x0d,0x49,0xc1,0xf8,0x00,0x31,
+0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,0x4f,0xf4,0x00,0x03,0x01,0x3b,0xd1,0xf8,
+0xd0,0x23,0x09,0xd0,0x12,0xf0,0x01,0x0f,0xf8,0xd0,0x12,0xf0,0x02,0x0f,0x0c,0xbf,
+0x6f,0xf0,0x01,0x00,0x00,0x20,0x70,0x47,0x4f,0xf0,0xff,0x30,0x70,0x47,0x00,0xbf,
+0x00,0x30,0x04,0x40,0x05,0x22,0x0d,0x4b,0xc3,0xf8,0x04,0x21,0xbf,0xf3,0x4f,0x8f,
+0xbf,0xf3,0x6f,0x8f,0x01,0x22,0xc3,0xf8,0x00,0x21,0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,
+0x6f,0x8f,0x4f,0xf4,0x00,0x02,0xd3,0xf8,0xd0,0x03,0x10,0xf0,0x04,0x00,0x00,0xd1,
+0x70,0x47,0x01,0x3a,0xf7,0xd1,0x4f,0xf0,0xff,0x30,0x70,0x47,0x00,0x30,0x04,0x40,
+0x01,0x22,0x0a,0x4b,0xc3,0xf8,0x00,0x28,0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,
+0xd3,0xf8,0x08,0x08,0x20,0xf0,0xff,0x40,0x20,0xf4,0xfc,0x00,0x00,0x0c,0x00,0x04,
+0xb0,0xf1,0x00,0x40,0x18,0xbf,0x4f,0xf0,0xff,0x30,0x70,0x47,0x00,0x70,0x04,0x40,
+0x01,0x22,0x05,0x4b,0xc3,0xf8,0x04,0x28,0xbf,0xf3,0x4f,0x8f,0xbf,0xf3,0x6f,0x8f,
+0xd3,0xf8,0x08,0x08,0xc0,0x17,0x70,0x47,0x00,0x70,0x04,0x40,0x08,0xb5,0x01,0x46,
+0xff,0xf7,0xb8,0xff,0x88,0xb9,0x42,0x22,0x09,0x4b,0x21,0xf0,0x0f,0x01,0xc3,0xf8,
+0xd0,0x01,0xc3,0xf8,0xd4,0x01,0xc3,0xf8,0x10,0x02,0xc3,0xf8,0x04,0x21,0xc3,0xf8,
+0x20,0x11,0xbd,0xe8,0x08,0x40,0xff,0xf7,0x83,0xbf,0x4f,0xf0,0xff,0x30,0x08,0xbd,
+0x00,0x30,0x04,0x40,0x2d,0xe9,0xf0,0x47,0x80,0x46,0x89,0x46,0x14,0x46,0x01,0x26,
+0x23,0x4d,0x24,0x4f,0x0c,0xb9,0x20,0x46,0x13,0xe0,0x10,0x2c,0xa2,0x46,0x28,0xbf,
+0x4f,0xf0,0x10,0x0a,0x06,0xfa,0x0a,0xf1,0x08,0x2c,0x01,0xf1,0xff,0x31,0x94,0xbf,
+0x41,0xf4,0x80,0x31,0x41,0xf4,0x40,0x31,0xff,0xf7,0x84,0xff,0x18,0xb1,0x4f,0xf0,
+0xff,0x30,0xbd,0xe8,0xf0,0x87,0x42,0x46,0x29,0xf0,0x0f,0x03,0xc5,0xf8,0xd0,0x01,
+0xc5,0xf8,0xd4,0x01,0xc5,0xf8,0x10,0x02,0xc5,0xf8,0x04,0x61,0xc5,0xf8,0x24,0x11,
+0xc5,0xf8,0x20,0x31,0xc9,0xf3,0x01,0x13,0xc5,0xf8,0x2c,0x31,0x93,0x78,0x51,0x78,
+0x1b,0x04,0x43,0xea,0x01,0x23,0x11,0x78,0x04,0x32,0x0b,0x43,0x12,0xf8,0x01,0x1c,
+0x43,0xea,0x01,0x63,0xc3,0x51,0x04,0x30,0x82,0x45,0xef,0xd8,0xff,0xf7,0x38,0xff,
+0x00,0x28,0xd4,0xd1,0xd1,0x44,0xd0,0x44,0xa4,0xeb,0x0a,0x04,0xba,0xe7,0x00,0xbf,
+0x00,0x30,0x04,0x40,0x30,0x31,0x04,0x40,
diff --git a/contrib/loaders/flash/am13e230x/flash.c b/contrib/loaders/flash/am13e230x/flash.c
new file mode 100644
index 000000000..e9d0b1510
--- /dev/null
+++ b/contrib/loaders/flash/am13e230x/flash.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/******************************************************************************
+ *
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Flash operations for AM13E230X, translated from the OpenOCD driver
+ * (src/flash/nor/am13e230x.c) to run on-device with direct register access.
+ *
+ * Memory barriers (__DSB/__ISB) are required around CMDEXEC writes per the
+ * SDK's DL_FlashCTL_executeCommand â the Cortex-M33 write buffer can
+ * reorder peripheral writes without them.
+ *
+ *****************************************************************************/
+
+#include "flash.h"
+
+/*
+ * ARM Cortex-M memory barrier intrinsics.
+ * These are compiler built-ins for DSB and ISB instructions.
+ */
+#define __DSB() __asm volatile("dsb 0xF" ::: "memory")
+#define __ISB() __asm volatile("isb 0xF" ::: "memory")
+
+int flash_request_gsc_semaphore(void)
+{
+ HWREG(GSC_REG_FPC_FLSEMREQ) = 0x00000001;
+ /* Ensure the semaphore request write reaches the peripheral before
+ * reading FLSEMSTAT */
+ __DSB();
+ __ISB();
+ uint32_t stat = HWREG(GSC_REG_FPC_FLSEMSTAT);
+ /* ASSIGNED must be set and DBGACC must be clear (CPU holds it) */
+ if ((stat & (GSC_FLSEMSTAT_ASSIGNED | GSC_FLSEMSTAT_DBGACC)) != GSC_FLSEMSTAT_ASSIGNED)
+ return -1;
+ return 0;
+}
+
+int flash_clear_gsc_semaphore(void)
+{
+ HWREG(GSC_REG_FPC_FLSEMCLR) = 0x00000001;
+ __DSB();
+ __ISB();
+ uint32_t stat = HWREG(GSC_REG_FPC_FLSEMSTAT);
+ /* ASSIGNED must be clear (semaphore released) */
+ if (stat & GSC_FLSEMSTAT_ASSIGNED)
+ return -1;
+ return 0;
+}
+
+/*
+ * Execute a flash command and wait for completion.
+ * Must be called after all command registers (CMDTYPE, CMDADDR, etc.)
+ * are configured. Matches the SDK's DL_FlashCTL_executeCommand.
+ *
+ * Returns 0 on success, -1 on timeout, -2 on command failure.
+ */
+static int flash_execute_cmd(void)
+{
+ /* Ensure all config register writes complete before execute */
+ __DSB();
+ __ISB();
+
+ HWREG(FCTL_REG_CMDEXEC) = FCTL_CMDEXEC_EXECUTE;
+
+ /* Ensure execute write completes before polling status */
+ __DSB();
+ __ISB();
+
+ uint32_t status;
+ uint32_t timeout = FLASH_TIMEOUT;
+
+ do {
+ status = HWREG(FCTL_REG_STATCMD);
+ if (--timeout == 0)
+ return -1;
+ } while ((status & FCTL_STATCMD_CMDDONE) == 0);
+
+ if ((status & FCTL_STATCMD_CMDPASS) == 0)
+ return -2;
+
+ return 0;
+}
+
+/*
+ * Clear the STATCMD register by issuing a CLEARSTATUS command.
+ * Must be called before each erase operation.
+ */
+static int flash_clear_status(void)
+{
+ HWREG(FCTL_REG_CMDTYPE) = FCTL_CMDTYPE_CLEARSTATUS;
+
+ __DSB();
+ __ISB();
+
+ HWREG(FCTL_REG_CMDEXEC) = FCTL_CMDEXEC_EXECUTE;
+
+ __DSB();
+ __ISB();
+
+ uint32_t timeout = FLASH_TIMEOUT;
+ while (HWREG(FCTL_REG_STATCMD) & FCTL_STATCMD_CMDINPROGRESS) {
+ if (--timeout == 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Unprotect all sectors by clearing protection registers.
+ * Protection is automatically re-enabled by hardware after each operation.
+ */
+static void flash_unprotect(void)
+{
+ HWREG(FCTL_REG_CMDWEPROTA) = 0;
+ HWREG(FCTL_REG_CMDWEPROTB) = 0;
+ HWREG(FCTL_REG_CMDWEPROTNM) = 0;
+}
+
+int flash_sector_erase(uint32_t addr)
+{
+ if (flash_clear_status() != 0)
+ return -1;
+
+ flash_unprotect();
+
+ HWREG(FCTL_REG_CMDTYPE) = FCTL_CMDTYPE_ERASE | FCTL_CMDTYPE_SIZE_SECTOR;
+ HWREG(FCTL_REG_CMDADDR) = addr & 0xFFFFFFF0;
+
+ return flash_execute_cmd();
+}
+
+int flash_write_sector(const uint8_t *data, uint32_t addr, uint32_t count)
+{
+ while (count > 0) {
+ uint32_t num_bytes = (count < FLASH_WORD_SIZE) ? count : FLASH_WORD_SIZE;
+ uint32_t num_send = num_bytes;
+ const uint8_t *write_buf = data;
+
+ /* Byte enable: one bit per data byte + ECC chunk bits */
+ uint32_t bytes_en = (1u << num_send) - 1;
+ bytes_en |= (1u << 16); /* ECC chunk 0 */
+ if (num_send > 8)
+ bytes_en |= (1u << 17); /* ECC chunk 1 */
+
+ /* SDK calls executeClearStatus + unprotect before every word write */
+ if (flash_clear_status() != 0)
+ return -1;
+ flash_unprotect();
+
+ HWREG(FCTL_REG_CMDTYPE) = FCTL_CMDTYPE_PROGRAM | FCTL_CMDTYPE_SIZE_ONEWORD;
+ HWREG(FCTL_REG_CMDBYTEN) = bytes_en;
+ HWREG(FCTL_REG_CMDADDR) = addr & 0xFFFFFFF0;
+
+ /* Flash word index: (address >> 4) & 3, per SDK */
+ HWREG(FCTL_REG_CMDDATAINDEX) = (addr >> 4) & 3;
+
+ /* Write data to flash data register (up to 4 x 32-bit words) */
+ volatile uint32_t *data_reg = (volatile uint32_t *)FCTL_REG_CMDDATA0;
+ for (uint32_t i = 0; i < num_send; i += 4) {
+ data_reg[i / 4] = (uint32_t)write_buf[i]
+ | ((uint32_t)write_buf[i + 1] << 8)
+ | ((uint32_t)write_buf[i + 2] << 16)
+ | ((uint32_t)write_buf[i + 3] << 24);
+ }
+
+ if (flash_execute_cmd() != 0)
+ return -1;
+
+ addr += num_bytes;
+ data += num_bytes;
+ count -= num_bytes;
+ }
+
+ return 0;
+}
diff --git a/contrib/loaders/flash/am13e230x/flash.h b/contrib/loaders/flash/am13e230x/flash.h
new file mode 100644
index 000000000..5e026c33f
--- /dev/null
+++ b/contrib/loaders/flash/am13e230x/flash.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/******************************************************************************
+ *
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Flash register definitions and operation prototypes for AM13E230X.
+ * Derived from src/flash/nor/am13e230x.c
+ *
+ *****************************************************************************/
+
+#ifndef OPENOCD_LOADERS_FLASH_AM13E230X_FLASH_H
+#define OPENOCD_LOADERS_FLASH_AM13E230X_FLASH_H
+
+#include <stdint.h>
+
+/* Direct 32-bit register access */
+#define HWREG(x) (*((volatile uint32_t *)(x)))
+
+/*
+ * Flash Controller (FCTL) registers
+ * Base: 0x40042000
+ * Register block offset: 0x1000
+ */
+#define FLASH_CONTROL_BASE 0x40042000
+
+#define FCTL_REG_CMDEXEC (FLASH_CONTROL_BASE + 0x1100)
+#define FCTL_REG_CMDTYPE (FLASH_CONTROL_BASE + 0x1104)
+#define FCTL_REG_CMDADDR (FLASH_CONTROL_BASE + 0x1120)
+#define FCTL_REG_CMDBYTEN (FLASH_CONTROL_BASE + 0x1124)
+#define FCTL_REG_CMDDATAINDEX (FLASH_CONTROL_BASE + 0x112C)
+#define FCTL_REG_CMDDATA0 (FLASH_CONTROL_BASE + 0x1130)
+#define FCTL_REG_CMDWEPROTA (FLASH_CONTROL_BASE + 0x11D0)
+#define FCTL_REG_CMDWEPROTB (FLASH_CONTROL_BASE + 0x11D4)
+#define FCTL_REG_CMDWEPROTNM (FLASH_CONTROL_BASE + 0x1210)
+#define FCTL_REG_STATCMD (FLASH_CONTROL_BASE + 0x13D0)
+
+/* STATCMD bits */
+#define FCTL_STATCMD_CMDDONE 0x00000001
+#define FCTL_STATCMD_CMDPASS 0x00000002
+#define FCTL_STATCMD_CMDINPROGRESS 0x00000004
+
+/* CMDEXEC bits */
+#define FCTL_CMDEXEC_EXECUTE 0x00000001
+
+/* CMDTYPE command field */
+#define FCTL_CMDTYPE_PROGRAM 0x00000001
+#define FCTL_CMDTYPE_ERASE 0x00000002
+#define FCTL_CMDTYPE_CLEARSTATUS 0x00000005
+
+/* CMDTYPE size field */
+#define FCTL_CMDTYPE_SIZE_ONEWORD 0x00000000
+#define FCTL_CMDTYPE_SIZE_SECTOR 0x00000040
+
+/*
+ * GSC (Global System Control) flash semaphore registers
+ */
+#define GSC_BASE 0x40046000
+#define GSC_REG_FPC_FLSEMREQ (GSC_BASE + 0x1800)
+#define GSC_REG_FPC_FLSEMCLR (GSC_BASE + 0x1804)
+#define GSC_REG_FPC_FLSEMSTAT (GSC_BASE + 0x1808)
+
+/* FLSEMSTAT bits */
+#define GSC_FLSEMSTAT_DBGACC 0x00010000 /* 1 = held by debug probe */
+#define GSC_FLSEMSTAT_ASSIGNED 0x80000000 /* 1 = semaphore is held */
+
+/* Flash geometry */
+#define SECTOR_SIZE 0x800 /* 2KB */
+#define FLASH_WORD_SIZE 16 /* 128-bit = 16 bytes */
+
+/* Flash region bases */
+#define FLASH_BASE_MAIN 0x00000000
+
+/* Timeout loop count */
+#define FLASH_TIMEOUT 0x00800000
+
+/*
+ * Flash operation functions
+ */
+
+/* Acquire/release GSC flash semaphore. Return 0 on success, -1 on failure. */
+int flash_request_gsc_semaphore(void);
+int flash_clear_gsc_semaphore(void);
+
+/* Erase a single sector at the given address */
+int flash_sector_erase(uint32_t addr);
+
+/* Write count bytes from data to flash at addr (handles 16-byte word writes) */
+int flash_write_sector(const uint8_t *data, uint32_t addr, uint32_t count);
+
+#endif /* OPENOCD_LOADERS_FLASH_AM13E230X_FLASH_H */
diff --git a/contrib/loaders/flash/am13e230x/main.c b/contrib/loaders/flash/am13e230x/main.c
new file mode 100644
index 000000000..6329d14f3
--- /dev/null
+++ b/contrib/loaders/flash/am13e230x/main.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/******************************************************************************
+ *
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * AM13E230X Flash Loader Overview:
+ * --------------------------------
+ * This is a bare-metal flash programming algorithm for the AM13E230X
+ * microcontroller. OpenOCD loads the compiled binary into device SRAM
+ * at 0x20000000 and starts execution. OpenOCD then streams flash data
+ * into two sector-sized (2 KB) SRAM buffers via the debug probe using
+ * a shared-memory handshake protocol identical to the CC26xx loader.
+ *
+ * The algorithm runs an infinite loop, waiting for OpenOCD to fill a buffer
+ * and signal readiness. It then erases the target sector and programs the
+ * buffer contents into flash. Two buffers are used in ping-pong fashion so
+ * that OpenOCD can fill the next buffer while the current one is being
+ * programmed.
+ *
+ * Shared-Memory Protocol
+ * ----------------------
+ * Communication uses two parameter blocks and two data buffers at fixed
+ * SRAM addresses:
+ *
+ * Address Content
+ * ---------- -------
+ * 0x20002000 flash_params[0] (20 bytes)
+ * 0x20002014 flash_params[1] (20 bytes)
+ * 0x20002100 buffer[0] (2048 bytes)
+ * 0x20002900 buffer[1] (2048 bytes)
+ *
+ * struct flash_params {
+ * uint32_t dest; // Flash destination address
+ * uint32_t len; // Number of bytes in buffer
+ * uint32_t cmd; // Command (see below)
+ * uint32_t status; // BUFFER_FULL=0xFFFFFFFF / BUFFER_EMPTY=0x0
+ * uint32_t buf_addr; // Address of associated data buffer
+ * };
+ *
+ * Commands:
+ * 0 CMD_NO_ACTION Do nothing
+ * 1 CMD_PROGRAM Program buffer contents to flash
+ * 2 CMD_ERASE_AND_PROGRAM Erase sector, then program
+ * 3 CMD_ERASE_SECTORS Erase sectors in range [dest, dest+len)
+ *
+ * Sequence (per sector):
+ * 1. OpenOCD writes sector data to buffer[N]
+ * 2. OpenOCD writes dest, len, cmd to params[N]
+ * 3. OpenOCD writes BUFFER_FULL (0xFFFFFFFF) to params[N].status
+ * 4. Algorithm sees BUFFER_FULL, performs erase + program
+ * 5. Algorithm writes BUFFER_EMPTY (0x0) to params[N].status
+ * 6. OpenOCD polls params[N].status, sees EMPTY, proceeds to next
+ * 7. Meanwhile, algorithm moves to params[N^1] (ping-pong)
+ *
+ * On error, the algorithm writes an error code (non-zero, non-0xFFFFFFFF)
+ * to params[N].status and enters an infinite loop.
+ *
+ *****************************************************************************/
+
+#include <stdint.h>
+#include "flash.h"
+
+/* Handshake values */
+#define BUFFER_EMPTY 0x00000000
+#define BUFFER_FULL 0xFFFFFFFF
+
+/* Commands */
+#define CMD_NO_ACTION 0
+#define CMD_PROGRAM 1
+#define CMD_ERASE_AND_PROGRAM 2
+#define CMD_ERASE_SECTORS 3
+
+/* Status codes written on error */
+#define STATUS_OK 0x00000000
+#define STATUS_FAILED_ERASE 0x00000101
+#define STATUS_FAILED_PROGRAM 0x00000102
+#define STATUS_FAILED_UNKNOWN_CMD 0x00000103
+#define STATUS_FAILED_SEM_ACQUIRE 0x00000104
+#define STATUS_FAILED_SEM_RELEASE 0x00000105
+
+/* Parameter block -- must match the OpenOCD driver's struct */
+struct __attribute__((packed)) flash_params {
+ uint32_t dest; /* Flash destination address */
+ uint32_t len; /* Number of bytes */
+ uint32_t cmd; /* Command */
+ uint32_t status; /* Handshake: BUFFER_FULL / BUFFER_EMPTY */
+ uint32_t buf_addr; /* Address of data buffer */
+};
+
+/* Params and buffers placed at fixed addresses by the linker script */
+__attribute__((section(".buffers.params")))
+volatile struct flash_params g_params[2];
+
+__attribute__((section(".buffers.buf0")))
+uint8_t g_buf0[SECTOR_SIZE];
+
+__attribute__((section(".buffers.buf1")))
+uint8_t g_buf1[SECTOR_SIZE];
+
+static int do_erase_and_program(volatile struct flash_params *p)
+{
+ /* Erase the target sector */
+ if (flash_sector_erase(p->dest) != 0)
+ return STATUS_FAILED_ERASE;
+
+ /* Program the buffer contents */
+ if (flash_write_sector((const uint8_t *)p->buf_addr, p->dest, p->len) != 0)
+ return STATUS_FAILED_PROGRAM;
+
+ return STATUS_OK;
+}
+
+static int do_program(volatile struct flash_params *p)
+{
+ if (flash_write_sector((const uint8_t *)p->buf_addr, p->dest, p->len) != 0)
+ return STATUS_FAILED_PROGRAM;
+
+ return STATUS_OK;
+}
+
+static int do_erase_sectors(volatile struct flash_params *p)
+{
+ uint32_t addr = p->dest;
+ uint32_t len = p->len;
+
+ /* Guard against dest+len wrapping past UINT32_MAX */
+ if (len > (UINT32_MAX - addr))
+ return STATUS_FAILED_ERASE;
+
+ uint32_t end = addr + len;
+
+ while (addr < end) {
+ if (flash_sector_erase(addr) != 0)
+ return STATUS_FAILED_ERASE;
+ addr += SECTOR_SIZE;
+ }
+
+ return STATUS_OK;
+}
+
+int main(void)
+{
+ uint32_t curr_buf = 0;
+ uint32_t status;
+
+ /* Initialize buffer pointers so OpenOCD can read them */
+ g_params[0].buf_addr = (uint32_t)g_buf0;
+ g_params[1].buf_addr = (uint32_t)g_buf1;
+ g_params[0].status = BUFFER_EMPTY;
+ g_params[1].status = BUFFER_EMPTY;
+
+ /* Acquire GSC flash semaphore â must be done by the CPU (not the
+ * debugger) because the flash controller checks FLSEMSTAT.DBGACC
+ * to verify the access source matches the semaphore holder. */
+ if (flash_request_gsc_semaphore() != 0) {
+ g_params[0].status = STATUS_FAILED_SEM_ACQUIRE;
+ while (1)
+ ;
+ }
+
+#ifdef ALGO_DRY_RUN
+ /* Dry-run mode: no flash operations, just ACK every command.
+ * Used to verify the shared-memory handshake works. */
+ while (1) {
+ while (g_params[curr_buf].status == BUFFER_EMPTY)
+ ;
+ g_params[curr_buf].status = BUFFER_EMPTY;
+ curr_buf ^= 1;
+ }
+#endif
+
+ while (1) {
+ /* Wait for OpenOCD to signal that buffer is ready */
+ while (g_params[curr_buf].status == BUFFER_EMPTY)
+ ;
+
+ /* Dispatch command */
+ switch (g_params[curr_buf].cmd) {
+ case CMD_ERASE_AND_PROGRAM:
+ status = do_erase_and_program(&g_params[curr_buf]);
+ break;
+ case CMD_PROGRAM:
+ status = do_program(&g_params[curr_buf]);
+ break;
+ case CMD_ERASE_SECTORS:
+ status = do_erase_sectors(&g_params[curr_buf]);
+ break;
+ default:
+ status = STATUS_FAILED_UNKNOWN_CMD;
+ break;
+ }
+
+ if (status != STATUS_OK) {
+ /* Report error and halt */
+ g_params[curr_buf].status = status;
+ if (flash_clear_gsc_semaphore() != 0)
+ g_params[curr_buf].status = STATUS_FAILED_SEM_RELEASE;
+ while (1)
+ ;
+ }
+
+ /* Signal completion */
+ g_params[curr_buf].status = BUFFER_EMPTY;
+
+ /* Swap to the other buffer */
+ curr_buf ^= 1;
+ }
+}
+
+void _exit(int status)
+{
+ (void)status;
+ while (1)
+ ;
+}
diff --git a/contrib/loaders/flash/am13e230x/startup.c b/contrib/loaders/flash/am13e230x/startup.c
new file mode 100644
index 000000000..26e5ced5f
--- /dev/null
+++ b/contrib/loaders/flash/am13e230x/startup.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/******************************************************************************
+ *
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Startup code for AM13E230X flash loader algorithm.
+ * OpenOCD jumps directly to entry() after loading the binary into SRAM.
+ *
+ *****************************************************************************/
+
+#include <stdint.h>
+
+extern int main(void);
+
+/* Stack: 100 words = 400 bytes (matches cc26xx) */
+__attribute__((section(".stack"), used))
+static uint32_t stack[100];
+
+/* BSS boundaries from linker */
+extern uint32_t _bss;
+extern uint32_t _ebss;
+/* Stack top from linker */
+extern uint32_t _estack;
+
+/*
+ * Entry point. OpenOCD sets PC here after loading the binary.
+ */
+__attribute__((section(".entry"), naked))
+void entry(void)
+{
+ /* Switch to privileged Thread mode using MSP.
+ * The previous application (e.g. Zephyr) may have set
+ * CONTROL.nPRIV=1 (unprivileged). Peripheral access
+ * requires privileged mode. */
+ __asm(" mov r0, #0");
+ __asm(" msr CONTROL, r0");
+ __asm(" isb");
+
+ /* Initialize stack pointer to top of .stack section */
+ __asm(" ldr sp, =_estack");
+
+ /* Zero fill the bss segment */
+ __asm(" ldr r0, =_bss\n"
+ " ldr r1, =_ebss\n"
+ " mov r2, #0\n"
+ " .thumb_func\n"
+ " zero_loop:\n"
+ " cmp r0, r1\n"
+ " it lt\n"
+ " strlt r2, [r0], #4\n"
+ " blt zero_loop");
+
+ /* Call the application's entry point */
+ __asm(" bl main");
+
+ /* If we ever return, infinite loop */
+ __asm(" halt_loop:\n"
+ " b halt_loop");
+}
-----------------------------------------------------------------------
Summary of changes:
contrib/loaders/flash/am13e230x/Makefile | 48 ++
contrib/loaders/flash/am13e230x/am13e230x.lds | 67 ++
contrib/loaders/flash/am13e230x/am13e230x_algo.inc | 49 ++
contrib/loaders/flash/am13e230x/flash.c | 177 +++++
contrib/loaders/flash/am13e230x/flash.h | 91 +++
contrib/loaders/flash/am13e230x/main.c | 216 ++++++
contrib/loaders/flash/am13e230x/startup.c | 60 ++
doc/openocd.texi | 64 ++
src/flash/nor/Makefile.am | 1 +
src/flash/nor/am13e230x.c | 758 +++++++++++++++++++++
src/flash/nor/driver.h | 1 +
src/flash/nor/drivers.c | 1 +
12 files changed, 1533 insertions(+)
create mode 100644 contrib/loaders/flash/am13e230x/Makefile
create mode 100644 contrib/loaders/flash/am13e230x/am13e230x.lds
create mode 100644 contrib/loaders/flash/am13e230x/am13e230x_algo.inc
create mode 100644 contrib/loaders/flash/am13e230x/flash.c
create mode 100644 contrib/loaders/flash/am13e230x/flash.h
create mode 100644 contrib/loaders/flash/am13e230x/main.c
create mode 100644 contrib/loaders/flash/am13e230x/startup.c
create mode 100644 src/flash/nor/am13e230x.c
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-12 08:06: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 0cc2812da831c57a4cc51f8f2f24de2ad8f324b4 (commit)
from bedefa238476ad852b1fafd927230e38e2092282 (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 0cc2812da831c57a4cc51f8f2f24de2ad8f324b4
Author: Tomas Vanek <va...@fb...>
Date: Fri Sep 4 07:23:51 2026 +0200
target/riscv: fix compilation on old gcc
gcc 4.8.4 complains
src/target/riscv/riscv-013.c:349:16: error: missing initializer
for field 'XLEN' of 'const struct riscv_debug_reg_ctx'
[-Werror=missing-field-initializers]
const struct riscv_debug_reg_ctx default_context = {0};
^
because struct riscv_debug_reg_ctx contains 3 sub-structs.
Initialize one sub-struct to make gcc happy.
Change-Id: I58dc2544a9a6be91f3dbe5a5b700350ede71afb7
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9956
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 449175634..96033af6f 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -346,7 +346,9 @@ static void riscv013_dm_free(struct target *target)
static struct riscv_debug_reg_ctx get_riscv_debug_reg_ctx(const struct target *target)
{
if (!target_was_examined(target)) {
- const struct riscv_debug_reg_ctx default_context = {0};
+ const struct riscv_debug_reg_ctx default_context = {
+ .XLEN = { 0 }
+ };
return default_context;
}
-----------------------------------------------------------------------
Summary of changes:
src/target/riscv/riscv-013.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-08 08:16:18
|
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 bedefa238476ad852b1fafd927230e38e2092282 (commit)
from 8a6cf324c618c7bccc7cb61f7e533d69022e6e97 (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 bedefa238476ad852b1fafd927230e38e2092282
Author: Samuel Obuch <sam...@es...>
Date: Wed Aug 19 07:45:45 2026 +0200
target/xtensa: flush cached registers before starting an algorithm
In case any aX registers are already dirty, modifying arY registers
for the algorithm run will cause these values to be lost. Resolve
inconsistencies in xtensa_write_dirty_registers, so that registers
do not have to be re-fetched from the target.
Change-Id: I483017fbae3d71a08d2212f27ebbe1c696437bd8
Signed-off-by: Samuel Obuch <sam...@es...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9924
Reviewed-by: Antonio Borneo <bor...@gm...>
Reviewed-by: Tomas Vanek <va...@fb...>
Tested-by: jenkins
Reviewed-by: Ian Thompson <ia...@ca...>
diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c
index d1a08c3bd..d3b297403 100644
--- a/src/target/xtensa/xtensa.c
+++ b/src/target/xtensa/xtensa.c
@@ -793,6 +793,10 @@ static int xtensa_write_dirty_registers(struct target *target)
j - XT_REG_IDX_AR0,
buf_get_u32(reg_list[j].value, 0, 32));
}
+ } else if (reg_list[i].dirty) {
+ memcpy(reg_list[j].value, reg_list[i].value, sizeof(xtensa_reg_val_t));
+ } else if (reg_list[j].dirty) {
+ memcpy(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t));
}
}
}
@@ -2741,6 +2745,12 @@ int xtensa_start_algorithm(struct target *target,
return ERROR_TARGET_NOT_HALTED;
}
+ retval = xtensa_write_dirty_registers(target);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Failed to write dirty regs (%d)", retval);
+ return retval;
+ }
+
for (unsigned int i = 0; i < xtensa->core_cache->num_regs; i++) {
struct reg *reg = &xtensa->core_cache->reg_list[i];
buf_cpy(reg->value, xtensa->algo_context_backup[i], reg->size);
-----------------------------------------------------------------------
Summary of changes:
src/target/xtensa/xtensa.c | 10 ++++++++++
1 file changed, 10 insertions(+)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-08 08:15:16
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 8a6cf324c618c7bccc7cb61f7e533d69022e6e97 (commit)
from 71576b70c75d17dc7b613a310b7797cd9b5dcfaa (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 8a6cf324c618c7bccc7cb61f7e533d69022e6e97
Author: Tomas Vanek <va...@fb...>
Date: Fri Aug 21 11:00:29 2026 +0200
jtag/drivers/cmsis_dap: add SWD transfer response size checks
First check if the adapter response is long enough to parse the header
safely. Then check response size during parsing DP/AP read response data.
Change-Id: I60d08e97d2458c375db97a83d319ef90a6978190
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9858
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index d3f32c98c..fda8d68e5 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -908,6 +908,34 @@ skip:
block->transfer_count = 0;
}
+static unsigned int cmsis_dap_tfer_cmd_size(unsigned int write_count,
+ unsigned int read_count, bool block_tfer)
+{
+ unsigned int size;
+ if (block_tfer) {
+ size = 5; /* DAP_TransferBlock header */
+ size += write_count * 4; /* data */
+ } else {
+ size = 3; /* DAP_Transfer header */
+ size += write_count * (1 + 4); /* DAP register + data */
+ size += read_count; /* DAP register */
+ }
+ return size;
+}
+
+static unsigned int cmsis_dap_tfer_resp_size(unsigned int write_count,
+ unsigned int read_count, bool block_tfer)
+{
+ unsigned int size;
+ if (block_tfer)
+ size = 4; /* DAP_TransferBlock response header */
+ else
+ size = 3; /* DAP_Transfer response header */
+
+ size += read_count * 4; /* data */
+ return size;
+}
+
static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blocking blocking)
{
int retval;
@@ -951,13 +979,24 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo
uint8_t *resp = dap->response;
if (resp[0] != block->command) {
- LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%x received 0x%" PRIx8,
- block->command, resp[0]);
+ LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%" PRIx8
+ " received 0x%" PRIx8, block->command, resp[0]);
cmsis_dap_swd_cancel_transfers(dap);
queued_retval = ERROR_FAIL;
return;
}
+ unsigned int resp_size = retval;
+ bool block_cmd = (block->command == CMD_DAP_TFER_BLOCK);
+ unsigned int expect_hdr_size = cmsis_dap_tfer_resp_size(0, 0, block_cmd);
+ if (resp_size < expect_hdr_size) {
+ LOG_ERROR("CMSIS-DAP too short response: expected header %u, got %u",
+ expect_hdr_size, resp_size);
+ cmsis_dap_swd_cancel_transfers(dap);
+ queued_retval = ERROR_JTAG_DEVICE_ERROR;
+ return;
+ }
+
unsigned int transfer_count;
unsigned int idx;
if (block->command == CMD_DAP_TFER_BLOCK) {
@@ -997,6 +1036,13 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo
struct pending_transfer_result *transfer = &(block->transfers[i]);
if (transfer->cmd & SWD_CMD_RNW) {
static uint32_t last_read;
+ if (idx + 4 > resp_size) {
+ LOG_ERROR("CMSIS-DAP too short response: expected at least %u, got %u",
+ idx + 4, resp_size);
+ cmsis_dap_swd_cancel_transfers(dap);
+ queued_retval = ERROR_JTAG_DEVICE_ERROR;
+ return;
+ }
uint32_t data = le_to_h_u32(&resp[idx]);
uint32_t tmp = data;
idx += 4;
@@ -1043,34 +1089,6 @@ static int cmsis_dap_swd_run_queue(void)
return retval;
}
-static unsigned int cmsis_dap_tfer_cmd_size(unsigned int write_count,
- unsigned int read_count, bool block_tfer)
-{
- unsigned int size;
- if (block_tfer) {
- size = 5; /* DAP_TransferBlock header */
- size += write_count * 4; /* data */
- } else {
- size = 3; /* DAP_Transfer header */
- size += write_count * (1 + 4); /* DAP register + data */
- size += read_count; /* DAP register */
- }
- return size;
-}
-
-static unsigned int cmsis_dap_tfer_resp_size(unsigned int write_count,
- unsigned int read_count, bool block_tfer)
-{
- unsigned int size;
- if (block_tfer)
- size = 4; /* DAP_TransferBlock response header */
- else
- size = 3; /* DAP_Transfer response header */
-
- size += read_count * 4; /* data */
- return size;
-}
-
static void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)
{
/* TARGETSEL register write cannot be queued */
-----------------------------------------------------------------------
Summary of changes:
src/jtag/drivers/cmsis_dap.c | 78 +++++++++++++++++++++++++++-----------------
1 file changed, 48 insertions(+), 30 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-08 08:14:45
|
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 71576b70c75d17dc7b613a310b7797cd9b5dcfaa (commit)
from 046c040cb0012e2f908bb11009b39bf502cff6f3 (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 71576b70c75d17dc7b613a310b7797cd9b5dcfaa
Author: Tomas Vanek <va...@fb...>
Date: Fri Aug 21 10:26:49 2026 +0200
jtag/drivers/cmsis_dap: add adapter info response size checks
Check the DAP_Info Command response length byte and return error
if info payload would overflow over response end.
Use the length byte to limit the number of character in the returned
info string to avoid problems in case the string is not properly
null terminated (e.g. when the adapter firmware does not conform
to CMSIS-DAP spec or accidentally getting the response of another
CMSIS-DAP command).
Reported-by: Antonio Borneo <bor...@gm...>
Change-Id: I4ee151b064b870def3f6b88abd059e578716db6e
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9857
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index d93ef51a9..d3f32c98c 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -479,6 +479,12 @@ static int cmsis_dap_cmd_dap_info(uint8_t info, uint8_t **data)
return ERROR_JTAG_DEVICE_ERROR;
}
+ unsigned int info_size = cmsis_dap_handle->response[1];
+ if (2 + info_size > cmsis_dap_handle->response_size) {
+ LOG_ERROR("CMSIS-DAP CMD_INFO payload (size %u) does not fit into response (size %u)",
+ info_size, cmsis_dap_handle->response_size);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
*data = &cmsis_dap_handle->response[1];
return ERROR_OK;
@@ -1163,7 +1169,7 @@ static int cmsis_dap_get_serial_info(void)
return retval;
if (data[0]) /* strlen */
- LOG_INFO("CMSIS-DAP: Serial# = %s", &data[1]);
+ LOG_INFO("CMSIS-DAP: Serial# = %.*s", data[0], &data[1]);
return ERROR_OK;
}
@@ -1178,7 +1184,7 @@ static int cmsis_dap_get_version_info(void)
return retval;
if (data[0]) /* strlen */
- LOG_INFO("CMSIS-DAP: FW Version = %s", &data[1]);
+ LOG_INFO("CMSIS-DAP: FW Version = %.*s", data[0], &data[1]);
return ERROR_OK;
}
-----------------------------------------------------------------------
Summary of changes:
src/jtag/drivers/cmsis_dap.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-07 13:31:17
|
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 046c040cb0012e2f908bb11009b39bf502cff6f3 (commit)
from e7170da28f90b0a835361b70dcea0623335b8bba (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 046c040cb0012e2f908bb11009b39bf502cff6f3
Author: Samuel Obuch <sam...@es...>
Date: Thu Aug 13 11:31:35 2026 +0200
contrib/loaders: keep clock gating enabled in esp32s3 reset handler
After reset, clock gating needs to be enabled, otherwise breakpoints
placed by user before it is enabled by the software will be lost.
Original author: Alexey Gerenkov <al...@es...>
Change-Id: I2a5bc78c7385787b41cf413077ef4277bffffe0f
Signed-off-by: Samuel Obuch <sam...@es...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9923
Reviewed-by: Tomas Vanek <va...@fb...>
Tested-by: jenkins
diff --git a/contrib/loaders/reset/espressif/esp32/esp32_cpu_reset_handler.S b/contrib/loaders/reset/espressif/esp32/esp32_cpu_reset_handler.S
index 506d41e85..08c70f5d4 100644
--- a/contrib/loaders/reset/espressif/esp32/esp32_cpu_reset_handler.S
+++ b/contrib/loaders/reset/espressif/esp32/esp32_cpu_reset_handler.S
@@ -111,7 +111,9 @@ start:
/* Clear APP_CPU boot address */
movi a4, DPORT_APPCPU_CTRL_D_REG
s32i.n a5, a4, 0
- /* Clear APP_CPU clock gating */
+ /* Set APP_CPU clock gating
+ otherwise APP_CPU with debug module will be reset by SW at startup
+ and breakpoints set just after reset will be lost */
movi a4, DPORT_APPCPU_CTRL_B_REG
movi a3, DPORT_APPCPU_CLKGATE_EN
s32i.n a3, a4, 0
diff --git a/contrib/loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc b/contrib/loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc
index dc9702c62..5ea5a7828 100644
--- a/contrib/loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc
+++ b/contrib/loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc
@@ -13,5 +13,5 @@
0xff,0x59,0x04,0x41,0xe2,0xff,0x59,0x04,0x41,0xe2,0xff,0x59,0x04,0x41,0xe1,0xff,
0x31,0xe2,0xff,0x39,0x04,0x41,0xe1,0xff,0x31,0xe2,0xff,0x39,0x04,0x41,0xe1,0xff,
0x59,0x04,0x41,0xe1,0xff,0x0c,0x23,0x39,0x04,0x41,0xe0,0xff,0x0c,0x43,0x39,0x04,
-0x52,0x64,0x00,0x41,0xdf,0xff,0x31,0xdf,0xff,0x32,0x64,0x00,0x00,0x70,0x00,0x46,
+0x0c,0x23,0x39,0x04,0x41,0xdf,0xff,0x31,0xdf,0xff,0x39,0x04,0x00,0x70,0x00,0x46,
0xfe,0xff,
diff --git a/contrib/loaders/reset/espressif/esp32s3/esp32s3_cpu_reset_handler.S b/contrib/loaders/reset/espressif/esp32s3/esp32s3_cpu_reset_handler.S
index 5fc635725..f4d3611b4 100644
--- a/contrib/loaders/reset/espressif/esp32s3/esp32s3_cpu_reset_handler.S
+++ b/contrib/loaders/reset/espressif/esp32s3/esp32s3_cpu_reset_handler.S
@@ -118,15 +118,19 @@ start:
/* Clear APP_CPU boot address */
movi a4, SYSTEM_CORE_1_CONTROL_1_REG
s32i.n a5, a4, 0
- /* Clear APP_CPU clock gating */
+ /* Set APP_CPU clock gating */
movi a4, SYSTEM_CORE_1_CONTROL_0_REG
movi a3, SYSTEM_CONTROL_CORE_1_CLKGATE_EN
s32i.n a3, a4, 0
- /* Set and clear APP_CPU reset */
+ /* Set APP_CPU reset */
movi a4, SYSTEM_CORE_1_CONTROL_0_REG
movi a3, SYSTEM_CONTROL_CORE_1_RESETING
s32i.n a3, a4, 0
- s32i.n a5, a4, 0
+ /* Clear APP_CPU reset and
+ set APP_CPU clock gating otherwise APP_CPU will be reset by SW at startup
+ and breakpoints set just after reset will be lost */
+ movi a3, SYSTEM_CONTROL_CORE_1_CLKGATE_EN
+ s32i.n a3, a4, 0
/* Restore the reset vector to ROM */
movi a4, RTC_CNTL_RESET_STATE_REG
movi a3, RTC_CNTL_RESET_STATE_DEF
-----------------------------------------------------------------------
Summary of changes:
.../loaders/reset/espressif/esp32/esp32_cpu_reset_handler.S | 4 +++-
.../loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc | 2 +-
.../reset/espressif/esp32s3/esp32s3_cpu_reset_handler.S | 10 +++++++---
3 files changed, 11 insertions(+), 5 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-06 14:49:43
|
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 e7170da28f90b0a835361b70dcea0623335b8bba (commit)
from 767355829476f95b1c90b303d077cef2afaf223a (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 e7170da28f90b0a835361b70dcea0623335b8bba
Author: Antonio Borneo <bor...@gm...>
Date: Thu Sep 3 11:01:03 2026 +0200
flash/nor/max32xxx_qspi: drop FSF boilerplate
With SPDX tag, there is no need to keep such text in each file.
Drop it.
Change-Id: Ia66e86778c651268122e885606203e85a5cbd52a
Signed-off-by: Antonio Borneo <bor...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9954
Reviewed-by: Tomas Vanek <va...@fb...>
Reviewed-by: Henrik Mau <hen...@an...>
Reviewed-by: zapb <de...@za...>
Tested-by: jenkins
diff --git a/src/flash/nor/max32xxx_qspi.c b/src/flash/nor/max32xxx_qspi.c
index 0743cad44..4a350728b 100644
--- a/src/flash/nor/max32xxx_qspi.c
+++ b/src/flash/nor/max32xxx_qspi.c
@@ -9,19 +9,6 @@
* *
* Portions Copyright (C) 2025-2026 Analog Devices, Inc. *
* pet...@an... *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
-----------------------------------------------------------------------
Summary of changes:
src/flash/nor/max32xxx_qspi.c | 13 -------------
1 file changed, 13 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-06 14:48:53
|
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 767355829476f95b1c90b303d077cef2afaf223a (commit)
from c71aab122e05b31d3e56a5514babba9bbdfa6ac0 (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 767355829476f95b1c90b303d077cef2afaf223a
Author: Tomas Vanek <va...@fb...>
Date: Thu Aug 27 12:00:07 2026 +0200
checkpatch: add missing LOG_CUSTOM_LEVEL to log functions
The list of log functions in checkpatch.pl was not updated in
commit b63e065f2380 ("helper/log: add LOG_CUSTOM_LEVEL() macro").
Change-Id: I254a0f222306f97ec74e1919a660e8b96bb467bb
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9898
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/tools/scripts/checkpatch.pl b/tools/scripts/checkpatch.pl
index 010b7f43d..157e46c3e 100755
--- a/tools/scripts/checkpatch.pl
+++ b/tools/scripts/checkpatch.pl
@@ -628,7 +628,7 @@ our $logFunctions = qr{(?x:
} # !$OpenOCD
# OpenOCD specific: Begin: list log functions
our $logFunctions = qr{(?x:
- LOG_(?:TARGET_|)(?:DEBUG_IO|DEBUG|INFO|WARNING|ERROR|USER|USER_N|OUTPUT)
+ LOG_(?:TARGET_|)(?:DEBUG_IO|DEBUG|INFO|WARNING|ERROR|USER|USER_N|OUTPUT|CUSTOM_LEVEL)
)};
# OpenOCD specific: End
-----------------------------------------------------------------------
Summary of changes:
tools/scripts/checkpatch.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-06 14:46:02
|
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 c71aab122e05b31d3e56a5514babba9bbdfa6ac0 (commit)
via 3280595478bc2cdd5cd58b1a2069b3cf1d755f7c (commit)
from 70ea3c01b042f6aefd0fe7f92db416c0cec683e3 (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 c71aab122e05b31d3e56a5514babba9bbdfa6ac0
Author: Jan Matyas <jan...@co...>
Date: Fri Jun 12 15:34:01 2026 +0200
target/riscv: refactor scratch_reserve() - use standardized macros
The original author of this commit is Farid Khaidari, see [1].
This commit refactors the scratch_reserve()
- Replacing hardcoded bit manipulation with BIT() macro
- Using GENMASK_ULL() instead of hardcoded masks for sign extension
- Applying ALIGN_UP() macro for address alignment calculations
- Using DIV_ROUND_UP() instead of manual division with addition
[1] https://github.com/riscv-collab/riscv-openocd/
commit/9d4c94e51fdaba3290a16825e48f393b9650a321
Change-Id: Ic40923ef7d9ac5ca0ffb313c9d4fc6d1457d6bbb
Signed-off-by: Farid Khaydari <f.k...@sy...>
Signed-off-by: Jan Matyas <jan...@co...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9742
Reviewed-by: Evgeniy Naydanov <eu...@gm...>
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
Reviewed-by: Mark Zhuang <mar...@sp...>
Reviewed-by: Farid Khaidari <kha...@gm...>
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index ae5ca1052..449175634 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -1227,12 +1227,13 @@ static int scratch_reserve(struct target *target,
if (info->dataaccess == 1) {
/* Sign extend dataaddr. */
scratch->hart_address = info->dataaddr;
- if (info->dataaddr & (1<<11))
- scratch->hart_address |= 0xfffffffffffff000ULL;
+ if (info->dataaddr & BIT(DM_HARTINFO_DATAADDR_LENGTH - 1))
+ scratch->hart_address |=
+ GENMASK_ULL(riscv_xlen(target) - 1, DM_HARTINFO_DATAADDR_LENGTH);
/* Align. */
- scratch->hart_address = (scratch->hart_address + alignment - 1) & ~(alignment - 1);
+ scratch->hart_address = ALIGN_UP(scratch->hart_address, alignment);
- if ((size_bytes + scratch->hart_address - info->dataaddr + 3) / 4 <=
+ if (DIV_ROUND_UP(size_bytes + scratch->hart_address - info->dataaddr, 4) <=
info->datasize) {
scratch->memory_space = SPACE_DM_DATA;
scratch->debug_address = (scratch->hart_address - info->dataaddr) / 4;
@@ -1246,10 +1247,9 @@ static int scratch_reserve(struct target *target,
/* Allow for ebreak at the end of the program. */
unsigned int program_size = (program->instruction_count + 1) * 4;
- scratch->hart_address = (info->progbuf_address + program_size + alignment - 1) &
- ~(alignment - 1);
+ scratch->hart_address = ALIGN_UP(info->progbuf_address + program_size, alignment);
if ((info->progbuf_writable == YNM_YES) &&
- ((size_bytes + scratch->hart_address - info->progbuf_address + 3) / 4 <=
+ (DIV_ROUND_UP(size_bytes + scratch->hart_address - info->progbuf_address, 4) <=
info->progbufsize)) {
scratch->memory_space = SPACE_DMI_PROGBUF;
scratch->debug_address = (scratch->hart_address - info->progbuf_address) / 4;
@@ -1259,8 +1259,7 @@ static int scratch_reserve(struct target *target,
/* Option 3: User-configured memory area as scratch RAM */
if (target_alloc_working_area(target, size_bytes + alignment - 1,
&scratch->area) == ERROR_OK) {
- scratch->hart_address = (scratch->area->address + alignment - 1) &
- ~(alignment - 1);
+ scratch->hart_address = ALIGN_UP(scratch->area->address, alignment);
scratch->memory_space = SPACE_DMI_RAM;
scratch->debug_address = scratch->hart_address;
return ERROR_OK;
commit 3280595478bc2cdd5cd58b1a2069b3cf1d755f7c
Author: Jan Matyas <jan...@co...>
Date: Fri Jun 12 15:26:37 2026 +0200
target/riscv: fix bug in scratch_reserve
This commit fixes comparison in scratch_reserve function.
Original author of this fix is Farid Khaydari, see [1].
[1] https://github.com/riscv-collab/riscv-openocd/
commit/10f1659f5ef048486acf8ec9925d2c2e2b87f1dd
Change-Id: I64399fb640ffe3a77dd7e6692592e9dcf8986d9b
Signed-off-by: Farid Khaydari <f.k...@sy...>
Signed-off-by: Jan Matyas <jan...@co...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9741
Tested-by: jenkins
Reviewed-by: Mark Zhuang <mar...@sp...>
Reviewed-by: Antonio Borneo <bor...@gm...>
Reviewed-by: Evgeniy Naydanov <eu...@gm...>
Reviewed-by: Farid Khaidari <kha...@gm...>
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 4925f0604..ae5ca1052 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -1232,7 +1232,7 @@ static int scratch_reserve(struct target *target,
/* Align. */
scratch->hart_address = (scratch->hart_address + alignment - 1) & ~(alignment - 1);
- if ((size_bytes + scratch->hart_address - info->dataaddr + 3) / 4 >=
+ if ((size_bytes + scratch->hart_address - info->dataaddr + 3) / 4 <=
info->datasize) {
scratch->memory_space = SPACE_DM_DATA;
scratch->debug_address = (scratch->hart_address - info->dataaddr) / 4;
@@ -1249,7 +1249,7 @@ static int scratch_reserve(struct target *target,
scratch->hart_address = (info->progbuf_address + program_size + alignment - 1) &
~(alignment - 1);
if ((info->progbuf_writable == YNM_YES) &&
- ((size_bytes + scratch->hart_address - info->progbuf_address + 3) / 4 >=
+ ((size_bytes + scratch->hart_address - info->progbuf_address + 3) / 4 <=
info->progbufsize)) {
scratch->memory_space = SPACE_DMI_PROGBUF;
scratch->debug_address = (scratch->hart_address - info->progbuf_address) / 4;
-----------------------------------------------------------------------
Summary of changes:
src/target/riscv/riscv-013.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-06 14:44:55
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 70ea3c01b042f6aefd0fe7f92db416c0cec683e3 (commit)
from 0c5906dc9d908264b2ce1159a9d421ccb48fdc57 (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 70ea3c01b042f6aefd0fe7f92db416c0cec683e3
Author: Tomas Vanek <va...@fb...>
Date: Sat Aug 22 11:32:42 2026 +0200
target: change type of working area restore parameter to bool
in both target_free_working_area_restore()
and target_free_all_working_areas_restore()
Change-Id: I04ff9b7e536602fe42c7c4a91bc4454d9b12600f
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9865
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/target/target.c b/src/target/target.c
index 1b747f417..139db2147 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -2143,7 +2143,7 @@ static int target_restore_working_area(struct target *target, struct working_are
}
/* Restore the area's backup memory, if any, and return the area to the allocation pool */
-static int target_free_working_area_restore(struct target *target, struct working_area *area, int restore)
+static int target_free_working_area_restore(struct target *target, struct working_area *area, bool restore)
{
if (!area || area->free)
return ERROR_OK;
@@ -2173,13 +2173,13 @@ static int target_free_working_area_restore(struct target *target, struct workin
int target_free_working_area(struct target *target, struct working_area *area)
{
- return target_free_working_area_restore(target, area, 1);
+ return target_free_working_area_restore(target, area, true);
}
/* free resources and restore memory, if restoring memory fails,
* free up resources anyway
*/
-static void target_free_all_working_areas_restore(struct target *target, int restore)
+static void target_free_all_working_areas_restore(struct target *target, bool restore)
{
struct working_area *c = target->working_areas;
@@ -2205,7 +2205,7 @@ static void target_free_all_working_areas_restore(struct target *target, int res
void target_free_all_working_areas(struct target *target)
{
- target_free_all_working_areas_restore(target, 1);
+ target_free_all_working_areas_restore(target, true);
/* Now we have none or only one working area marked as free */
if (target->working_areas) {
@@ -5446,7 +5446,7 @@ COMMAND_HANDLER(handle_target_reset)
/* determine if we should halt or not. */
target->reset_halt = (a != 0);
/* When this happens - all workareas are invalid. */
- target_free_all_working_areas_restore(target, 0);
+ target_free_all_working_areas_restore(target, false);
/* do the assert */
if (n->value == NVP_ASSERT) {
-----------------------------------------------------------------------
Summary of changes:
src/target/target.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|
|
From: openocd-gerrit <ope...@us...> - 2026-09-06 14:44: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 0c5906dc9d908264b2ce1159a9d421ccb48fdc57 (commit)
via f4745331f1acb93c270e3f430a874caacf6ed61a (commit)
via 47fa0fdbb4c9622c85c9a3002cfe892c8f7fc656 (commit)
from 942bd99c1ba4f436e9309b7f7ba25e190f29604e (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 0c5906dc9d908264b2ce1159a9d421ccb48fdc57
Author: Tomas Vanek <va...@fb...>
Date: Sat Aug 22 11:21:51 2026 +0200
target: free working area even if restore fails
The change was proposed by REVISIT comment since 2011
commit 813f4a5411af ("target: rewrite working area allocator")
Ensure target_free_working_area() works same way as
target_free_all_working_areas() does.
Change-Id: Ib92ad7b6b127e45417153ee35430990cb7f6b58c
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9864
Reviewed-by: Antonio Borneo <bor...@gm...>
Tested-by: jenkins
diff --git a/src/target/target.c b/src/target/target.c
index f88689d5f..1b747f417 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -2149,12 +2149,8 @@ static int target_free_working_area_restore(struct target *target, struct workin
return ERROR_OK;
int retval = ERROR_OK;
- if (restore) {
+ if (restore)
retval = target_restore_working_area(target, area);
- /* REVISIT: Perhaps the area should be freed even if restoring fails. */
- if (retval != ERROR_OK)
- return retval;
- }
area->free = true;
commit f4745331f1acb93c270e3f430a874caacf6ed61a
Author: Tomas Vanek <va...@fb...>
Date: Sat Aug 22 11:18:28 2026 +0200
target: recommend to reset target when work area restore fails
While on it restructure target_restore_working_area() code.
Change-Id: I4fcf18d8c673ec86443da527915cee3a383a7496
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9863
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/src/target/target.c b/src/target/target.c
index c91f47c63..f88689d5f 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -2128,15 +2128,17 @@ int target_alloc_working_area(struct target *target, uint32_t size, struct worki
static int target_restore_working_area(struct target *target, struct working_area *area)
{
- int retval = ERROR_OK;
+ if (!target->backup_working_area || !area->backup)
+ return ERROR_OK;
- if (target->backup_working_area && area->backup) {
- retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup);
- if (retval != ERROR_OK)
- LOG_ERROR("failed to restore %" PRIu32 " bytes of working area at address " TARGET_ADDR_FMT,
- area->size, area->address);
+ int retval = target_write_memory(target, area->address, 4,
+ area->size / 4, area->backup);
+ if (retval != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "failed to restore %" PRIu32
+ " bytes of working area at address " TARGET_ADDR_FMT,
+ area->size, area->address);
+ LOG_TARGET_INFO(target, "'resume' would fail, reset the target");
}
-
return retval;
}
commit 47fa0fdbb4c9622c85c9a3002cfe892c8f7fc656
Author: Tomas Vanek <va...@fb...>
Date: Sat Aug 22 11:12:53 2026 +0200
target: log errors and clean up if work area backup fails
Call target_merge_working_areas() to clean up previously
split area.
Change-Id: I458e4331ed2f085d5349f4a6cd201ca95907ae3d
Signed-off-by: Tomas Vanek <va...@fb...>
Reviewed-on: https://review.openocd.org/c/openocd/+/9862
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/src/target/target.c b/src/target/target.c
index a5e967154..c91f47c63 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -2088,13 +2088,19 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w
if (target->backup_working_area) {
if (!c->backup) {
c->backup = malloc(c->size);
- if (!c->backup)
+ if (!c->backup) {
+ LOG_TARGET_ERROR(target, "No memory for working area backup");
+ target_merge_working_areas(target);
return ERROR_FAIL;
+ }
}
int retval = target_read_memory(target, c->address, 4, c->size / 4, c->backup);
- if (retval != ERROR_OK)
+ if (retval != ERROR_OK) {
+ LOG_TARGET_ERROR(target, "Working area backup failed");
+ target_merge_working_areas(target);
return retval;
+ }
}
/* mark as used, and return the new (reused) area */
-----------------------------------------------------------------------
Summary of changes:
src/target/target.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|