You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(57) |
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(14) |
Nov
(36) |
Dec
(7) |
2007 |
Jan
(48) |
Feb
(10) |
Mar
(17) |
Apr
(8) |
May
(35) |
Jun
(28) |
Jul
(50) |
Aug
(71) |
Sep
(40) |
Oct
(19) |
Nov
(22) |
Dec
(143) |
2008 |
Jan
(184) |
Feb
(549) |
Mar
(381) |
Apr
(388) |
May
(148) |
Jun
(128) |
Jul
(502) |
Aug
(243) |
Sep
(136) |
Oct
(327) |
Nov
(252) |
Dec
(475) |
2009 |
Jan
(344) |
Feb
(185) |
Mar
(338) |
Apr
(826) |
May
(1559) |
Jun
(1429) |
Jul
(817) |
Aug
(451) |
Sep
(639) |
Oct
(935) |
Nov
(1222) |
Dec
(826) |
2010 |
Jan
(552) |
Feb
(532) |
Mar
(355) |
Apr
(206) |
May
(162) |
Jun
(203) |
Jul
(168) |
Aug
(232) |
Sep
(270) |
Oct
(259) |
Nov
(439) |
Dec
(468) |
2011 |
Jan
(224) |
Feb
(249) |
Mar
(278) |
Apr
(381) |
May
(316) |
Jun
(637) |
Jul
(544) |
Aug
(465) |
Sep
(159) |
Oct
(440) |
Nov
(139) |
Dec
|
2012 |
Jan
(204) |
Feb
(383) |
Mar
(295) |
Apr
(196) |
May
(590) |
Jun
(158) |
Jul
(167) |
Aug
(177) |
Sep
(179) |
Oct
(301) |
Nov
(144) |
Dec
(173) |
2013 |
Jan
(299) |
Feb
(120) |
Mar
(238) |
Apr
(140) |
May
(69) |
Jun
(133) |
Jul
(160) |
Aug
(107) |
Sep
(164) |
Oct
(196) |
Nov
(105) |
Dec
(74) |
2014 |
Jan
(205) |
Feb
(156) |
Mar
(175) |
Apr
(181) |
May
(162) |
Jun
(158) |
Jul
(117) |
Aug
(109) |
Sep
(148) |
Oct
(106) |
Nov
(82) |
Dec
(72) |
2015 |
Jan
(191) |
Feb
(205) |
Mar
(197) |
Apr
(163) |
May
(136) |
Jun
(36) |
Jul
(79) |
Aug
(55) |
Sep
(64) |
Oct
(146) |
Nov
(142) |
Dec
(78) |
2016 |
Jan
(65) |
Feb
(190) |
Mar
(53) |
Apr
(38) |
May
(95) |
Jun
(53) |
Jul
(58) |
Aug
(113) |
Sep
(96) |
Oct
(59) |
Nov
(136) |
Dec
(124) |
2017 |
Jan
(80) |
Feb
(109) |
Mar
(163) |
Apr
(78) |
May
(61) |
Jun
(73) |
Jul
(29) |
Aug
(47) |
Sep
(60) |
Oct
(76) |
Nov
(48) |
Dec
(35) |
2018 |
Jan
(138) |
Feb
(84) |
Mar
(109) |
Apr
(49) |
May
(24) |
Jun
(62) |
Jul
(96) |
Aug
(116) |
Sep
(53) |
Oct
(99) |
Nov
(80) |
Dec
(88) |
2019 |
Jan
(100) |
Feb
(141) |
Mar
(72) |
Apr
(174) |
May
(129) |
Jun
(102) |
Jul
(52) |
Aug
(45) |
Sep
(28) |
Oct
(43) |
Nov
(78) |
Dec
(47) |
2020 |
Jan
(113) |
Feb
(72) |
Mar
(94) |
Apr
(141) |
May
(82) |
Jun
(68) |
Jul
(125) |
Aug
(76) |
Sep
(33) |
Oct
(184) |
Nov
(61) |
Dec
(95) |
2021 |
Jan
(109) |
Feb
(77) |
Mar
(145) |
Apr
(116) |
May
(134) |
Jun
(113) |
Jul
(71) |
Aug
(118) |
Sep
(116) |
Oct
(92) |
Nov
(124) |
Dec
(68) |
2022 |
Jan
(57) |
Feb
(61) |
Mar
(57) |
Apr
(74) |
May
(86) |
Jun
(80) |
Jul
(43) |
Aug
(85) |
Sep
(120) |
Oct
(88) |
Nov
(100) |
Dec
(108) |
2023 |
Jan
(39) |
Feb
(56) |
Mar
(92) |
Apr
(81) |
May
(84) |
Jun
(72) |
Jul
(182) |
Aug
(82) |
Sep
(54) |
Oct
(68) |
Nov
(67) |
Dec
(75) |
2024 |
Jan
(79) |
Feb
(65) |
Mar
(42) |
Apr
(47) |
May
(68) |
Jun
(111) |
Jul
(43) |
Aug
(73) |
Sep
(100) |
Oct
(35) |
Nov
(100) |
Dec
(99) |
2025 |
Jan
(71) |
Feb
(68) |
Mar
(44) |
Apr
(40) |
May
(92) |
Jun
(45) |
Jul
(86) |
Aug
(60) |
Sep
(76) |
Oct
(48) |
Nov
|
Dec
|
From: Daniel G. <dan...@gm...> - 2025-10-22 18:16:51
|
On Wed, Oct 22, 2025 at 05:51:50PM +0000, Neil Shipp wrote: > What is the most commonly used JTAG hardware these days with OpenOCD? I'd say either FTDI or CMSIS-DAP. I once made e57f8e12da6da02c192cd9365185fe8eee46b080 to remove this unnecessary DR-/IR-Pause step from the usb_blaster driver. The Ingenic JZ4730 discards changes to the DR and IR registers when passing through the pause state. Best regards, Daniel |
From: Neil S. <nl...@ya...> - 2025-10-22 17:52:00
|
On Wednesday, October 22, 2025 at 09:17:47 AM PDT, Paul Fertser <fer...@gm...> wrote: > Looks like it's an artifact of very early years of development, see > e.g. 4411c2643e41d023a1909b1040361912422be6c0 which supports your idea > that developers thought every scan should end in a stable state. > > All the drivers you mentioned are very rarely used for JTAGing these > days and there's hardly much motivation anyone has to try to improve > their performance. > > I see I removed that code from J-Link driver 10 years ago: > ae8cdc139e12a851107e8f882c5a166a21103ad4 hah :) so it's not just a > performance issue but also a problem for FPGA/CPLD interactions. Thank you for your insight. What is the most commonly used JTAG hardware these days with OpenOCD? Neil. |
From: Paul F. <fer...@gm...> - 2025-10-22 16:17:58
|
Hi, On Sun, Oct 19, 2025 at 11:15:32PM +0000, Neil Shipp wrote: > I've noticed that a number of JTAG drivers insert a transition to TAP_IRPAUSE or > TAP_DRPAUSE in their _execute_scan functions. The OpenJTAG, armjtagew, > buspirate, usbprog, and vsllink all do this. Other drivers such as ftdi bypass > the pause state in certain conditions. I believe the reason behind it is to > leave the JTAG state machine in a stable state between operations. Removing the > mandatory pause for long operations can give a non-trivial performance boost. Is > there any other reason to insert the pause state I'm not aware of? Looks like it's an artifact of very early years of development, see e.g. 4411c2643e41d023a1909b1040361912422be6c0 which supports your idea that developers thought every scan should end in a stable state. All the drivers you mentioned are very rarely used for JTAGing these days and there's hardly much motivation anyone has to try to improve their performance. I see I removed that code from J-Link driver 10 years ago: ae8cdc139e12a851107e8f882c5a166a21103ad4 hah :) so it's not just a performance issue but also a problem for FPGA/CPLD interactions. -- Be free, use free (http://www.gnu.org/philosophy/free-sw.html) software! mailto:fer...@gm... |
From: <ge...@op...> - 2025-10-21 18:33:53
|
This is an automated email from Gerrit. "Evgeniy Naydanov <evg...@sy...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9177 -- gerrit commit c4e746075e71467c38db03c7c0fe8bfb0eb23444 Author: Tim Newsome <ti...@si...> Date: Wed Aug 14 11:56:44 2019 -0700 server: rtos: don't fake step for hwthread rtos. This is a cherry-pick of: Link: https://github.com/riscv-collab/riscv-openocd/commit/efce094b409179acbaa7726c112a10fcf8343503 Fake step is a hack introduced to make things work with real RTOSs that have a concept of a current thread. The hwthread rtos always has access to all threads, so doesn't need it. This fixes a bug when running my MulticoreRegTest against HiFive Unleashed where OpenOCD would return the registers of the wrong thread after gdb stepped a hart. Change-Id: I64f538a133fb078c05a0c6b8121388b0b9d7f1b8 Signed-off-by: Tim Newsome <ti...@si...> diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c index b2a45ade9f..f7617ead7a 100644 --- a/src/rtos/hwthread.c +++ b/src/rtos/hwthread.c @@ -28,6 +28,7 @@ static int hwthread_read_buffer(struct rtos *rtos, target_addr_t address, uint32_t size, uint8_t *buffer); static int hwthread_write_buffer(struct rtos *rtos, target_addr_t address, uint32_t size, const uint8_t *buffer); +static bool hwthread_needs_fake_step(struct target *target, int64_t thread_id); #define HW_THREAD_NAME_STR_SIZE (32) @@ -59,6 +60,7 @@ const struct rtos_type hwthread_rtos = { .set_reg = hwthread_set_reg, .read_buffer = hwthread_read_buffer, .write_buffer = hwthread_write_buffer, + .needs_fake_step = hwthread_needs_fake_step }; struct hwthread_params { @@ -446,3 +448,8 @@ static int hwthread_write_buffer(struct rtos *rtos, target_addr_t address, return target_write_buffer(curr, address, size, buffer); } + +bool hwthread_needs_fake_step(struct target *target, int64_t thread_id) +{ + return false; +} diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 2ccccf1b0d..dc2b83ee82 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -730,3 +730,10 @@ int rtos_write_buffer(struct target *target, target_addr_t address, return target->rtos->type->write_buffer(target->rtos, address, size, buffer); return ERROR_NOT_IMPLEMENTED; } + +bool rtos_needs_fake_step(struct target *target, int64_t thread_id) +{ + if (target->rtos->type->needs_fake_step) + return target->rtos->type->needs_fake_step(target, thread_id); + return target->rtos->current_thread != thread_id; +} diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h index dbaa7e8ce8..c0a39771aa 100644 --- a/src/rtos/rtos.h +++ b/src/rtos/rtos.h @@ -77,6 +77,13 @@ struct rtos_type { uint8_t *buffer); int (*write_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size, const uint8_t *buffer); + /** + * Possibly work around an annoying gdb behaviour: when the current thread + * is changed in gdb, it assumes that the target can follow and also make + * the thread current. This is an assumption that cannot hold for a real + * target running a multi-threading OS. If an RTOS can do this, override + * needs_fake_step(). */ + bool (*needs_fake_step)(struct target *target, int64_t thread_id); }; struct stack_register_offset { @@ -135,6 +142,7 @@ int rtos_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer); int rtos_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer); +bool rtos_needs_fake_step(struct target *target, int64_t thread_id); // Keep in alphabetic order this list of rtos extern const struct rtos_type chibios_rtos; diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 080e3360ae..0cef8a8ba5 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -3075,8 +3075,21 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p } if (target->rtos) { - /* FIXME: why is this necessary? rtos state should be up-to-date here already! */ - rtos_update_threads(target); + /* Sometimes this results in picking a different thread than + * gdb just requested to step. Then we fake it, and now there's + * a different thread selected than gdb expects, so register + * accesses go to the wrong one! + * E.g.: + * Hg1$ + * P8=72101ce197869329$ # write r8 on thread 1 + * g$ + * vCont?$ + * vCont;s:1;c$ # rtos_update_threads changes to other thread + * g$ + * qXfer:threads:read::0,fff$ + * P8=cc060607eb89ca7f$ # write r8 on other thread + * g$ + * */ target->rtos->gdb_target_for_threadid(connection, thread_id, &ct); @@ -3084,8 +3097,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p * check if the thread to be stepped is the current rtos thread * if not, we must fake the step */ - if (target->rtos->current_thread != thread_id) - fake_step = true; + fake_step = rtos_needs_fake_step(target, thread_id); } if (parse[0] == ';') { -- |
From: <ge...@op...> - 2025-10-21 18:02:13
|
This is an automated email from Gerrit. "Evgeniy Naydanov <evg...@sy...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9176 -- gerrit commit f86c1deceea8db1da47e5537aae5c1daaeda28d4 Author: Tim Newsome <ti...@si...> Date: Mon Jan 31 09:23:38 2022 -0800 Ask the RTOS which target to set swbp on. This is the result of squashing two commits from RISC-V OpenOCD, the first one is commit 52ca5d198e3b4a0565e810ff4b5545dfac39cec9 ("Ask the RTOS which target to set swbp on. (#673)") and the second one is commit 8ae41e86e15df5df60cdf17a69ac2622570af6a7 ("Fix breackpoint_add for rtos swbp (#734)"). The resulting change lets the RTOS pick the "current" target for setting the hardware breakpoint on, which matters if address translation differs between threads. Change-Id: I67ce24d6aa0ca9225436b380065d1e265424e70f Signed-off-by: Tim Newsome <ti...@si...> Signed-off-by: Evgeniy Naydanov <evg...@sy...> diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c index b2a45ade9f..1d47b13223 100644 --- a/src/rtos/hwthread.c +++ b/src/rtos/hwthread.c @@ -28,6 +28,8 @@ static int hwthread_read_buffer(struct rtos *rtos, target_addr_t address, uint32_t size, uint8_t *buffer); static int hwthread_write_buffer(struct rtos *rtos, target_addr_t address, uint32_t size, const uint8_t *buffer); +struct target *hwthread_swbp_target(struct rtos *rtos, target_addr_t address, + uint32_t length, enum breakpoint_type type); #define HW_THREAD_NAME_STR_SIZE (32) @@ -59,6 +61,7 @@ const struct rtos_type hwthread_rtos = { .set_reg = hwthread_set_reg, .read_buffer = hwthread_read_buffer, .write_buffer = hwthread_write_buffer, + .swbp_target = hwthread_swbp_target }; struct hwthread_params { @@ -446,3 +449,9 @@ static int hwthread_write_buffer(struct rtos *rtos, target_addr_t address, return target_write_buffer(curr, address, size, buffer); } + +struct target *hwthread_swbp_target(struct rtos *rtos, target_addr_t address, + uint32_t length, enum breakpoint_type type) +{ + return hwthread_find_thread(rtos->target, rtos->current_thread); +} diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index 2ccccf1b0d..961bc40b13 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -730,3 +730,11 @@ int rtos_write_buffer(struct target *target, target_addr_t address, return target->rtos->type->write_buffer(target->rtos, address, size, buffer); return ERROR_NOT_IMPLEMENTED; } + +struct target *rtos_swbp_target(struct target *target, target_addr_t address, + uint32_t length, enum breakpoint_type type) +{ + if (target->rtos->type->swbp_target) + return target->rtos->type->swbp_target(target->rtos, address, length, type); + return target; +} diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h index dbaa7e8ce8..0fc361eba1 100644 --- a/src/rtos/rtos.h +++ b/src/rtos/rtos.h @@ -9,6 +9,7 @@ #define OPENOCD_RTOS_RTOS_H #include "server/server.h" +#include "target/breakpoints.h" #include "target/target.h" typedef int64_t threadid_t; @@ -77,6 +78,12 @@ struct rtos_type { uint8_t *buffer); int (*write_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size, const uint8_t *buffer); + /* When a software breakpoint is set, it is set on only one target, + * because we assume memory is shared across them. By default this is the + * first target in the SMP group. Override this function to have + * breakpoint_add() use a different target. */ + struct target * (*swbp_target)(struct rtos *rtos, target_addr_t address, + uint32_t length, enum breakpoint_type type); }; struct stack_register_offset { @@ -135,6 +142,8 @@ int rtos_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer); int rtos_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer); +struct target *rtos_swbp_target(struct target *target, target_addr_t address, + uint32_t length, enum breakpoint_type type); // Keep in alphabetic order this list of rtos extern const struct rtos_type chibios_rtos; diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 080e3360ae..b565cb5a12 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -1809,7 +1809,15 @@ static int gdb_breakpoint_watchpoint_packet(struct connection *connection, case 0: case 1: if (packet[0] == 'Z') { - retval = breakpoint_add(target, address, size, bp_type); + struct target *bp_target = target; + if (target->rtos && bp_type == BKPT_SOFT) { + bp_target = rtos_swbp_target(target, address, size, bp_type); + if (!bp_target) { + retval = ERROR_FAIL; + break; + } + } + retval = breakpoint_add(bp_target, address, size, bp_type); } else { assert(packet[0] == 'z'); retval = breakpoint_remove(target, address); diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index 7254eac7dc..4781842846 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -210,16 +210,10 @@ int breakpoint_add(struct target *target, unsigned int length, enum breakpoint_type type) { - if (target->smp) { - struct target_list *head; - - if (type == BKPT_SOFT) { - head = list_first_entry(target->smp_targets, struct target_list, lh); - return breakpoint_add_internal(head->target, address, length, type); - } - - foreach_smp_target(head, target->smp_targets) { - struct target *curr = head->target; + if (target->smp && type == BKPT_HARD) { + struct target_list *list_node; + foreach_smp_target(list_node, target->smp_targets) { + struct target *curr = list_node->target; int retval = breakpoint_add_internal(curr, address, length, type); if (retval != ERROR_OK) return retval; -- |
From: <ge...@op...> - 2025-10-21 13:18:02
|
This is an automated email from Gerrit. "Evgeniy Naydanov <evg...@sy...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9175 -- gerrit commit 45f7337d3a804141253f021de817d8faae9ed306 Author: Tim Newsome <ti...@si...> Date: Wed Apr 27 12:41:13 2022 -0700 Make `watchpoint.unique_id` a `uint32_t` Now it matches `breakpoint.unique_id`. Cherry-picked from Link: https://github.com/riscv-collab/riscv-openocd/commit/e8b05455e21079d0e0698235bf4b85bda6023875 Change-Id: I06f24b2cede2ee56bdeac8666b5235f923b18659 Signed-off-by: Tim Newsome <ti...@si...> diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index 7254eac7dc..ba550a7039 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -403,7 +403,7 @@ static int watchpoint_free(struct target *target, struct watchpoint *watchpoint_ return retval; } - LOG_TARGET_DEBUG(target, "free WPID: %d --> %d", watchpoint->unique_id, retval); + LOG_TARGET_DEBUG(target, "free WPID: %" PRIu32 " --> %d", watchpoint->unique_id, retval); (*watchpoint_p) = watchpoint->next; free(watchpoint); @@ -495,7 +495,7 @@ static int watchpoint_add_internal(struct target *target, target_addr_t address, || watchpoint->mask != mask || watchpoint->rw != rw) { LOG_TARGET_ERROR(target, "address " TARGET_ADDR_FMT - " already has watchpoint %d", + " already has watchpoint %" PRIu32, address, watchpoint->unique_id); return ERROR_FAIL; } @@ -635,7 +635,7 @@ int watchpoint_hit(struct target *target, enum watchpoint_rw *rw, *rw = hit_watchpoint->rw; *address = hit_watchpoint->address; - LOG_TARGET_DEBUG(target, "Found hit watchpoint at " TARGET_ADDR_FMT " (WPID: %d)", + LOG_TARGET_DEBUG(target, "Found hit watchpoint at " TARGET_ADDR_FMT " (WPID: %" PRIu32 ")", hit_watchpoint->address, hit_watchpoint->unique_id); diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h index d547a687fd..89572ffc5d 100644 --- a/src/target/breakpoints.h +++ b/src/target/breakpoints.h @@ -47,7 +47,7 @@ struct watchpoint { bool is_set; unsigned int number; struct watchpoint *next; - int unique_id; + uint32_t unique_id; }; int breakpoint_add(struct target *target, diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 42e9572602..a9285c5237 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2147,7 +2147,7 @@ static int cortex_m_set_watchpoint(struct target *target, struct watchpoint *wat target_write_u32(target, comparator->dwt_comparator_address + 8, comparator->function); - LOG_TARGET_DEBUG(target, "Watchpoint (ID %d) DWT%d 0x%08" PRIx32 " 0x%" PRIx32 " 0x%05" PRIx32, + LOG_TARGET_DEBUG(target, "Watchpoint (ID %" PRIu32 ") DWT%d 0x%08" PRIx32 " 0x%" PRIx32 " 0x%05" PRIx32, watchpoint->unique_id, dwt_num, comparator->comp, comparator->mask, comparator->function); return ERROR_OK; @@ -2159,14 +2159,14 @@ static int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *w struct cortex_m_dwt_comparator *comparator; if (!watchpoint->is_set) { - LOG_TARGET_WARNING(target, "watchpoint (wpid: %d) not set", + LOG_TARGET_WARNING(target, "watchpoint (wpid: %" PRIu32 ") not set", watchpoint->unique_id); return ERROR_OK; } unsigned int dwt_num = watchpoint->number; - LOG_TARGET_DEBUG(target, "Watchpoint (ID %d) DWT%u address: " TARGET_ADDR_FMT " clear", + LOG_TARGET_DEBUG(target, "Watchpoint (ID %" PRIu32 ") DWT%u address: " TARGET_ADDR_FMT " clear", watchpoint->unique_id, dwt_num, watchpoint->address); diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c index 8ad9d00fec..e7add095b4 100644 --- a/src/target/x86_32_common.c +++ b/src/target/x86_32_common.c @@ -1223,7 +1223,7 @@ static int set_watchpoint(struct target *t, struct watchpoint *wp) watchpoint_set(wp, wp_num); debug_reg_list[wp_num].used = 1; debug_reg_list[wp_num].bp_value = wp->address; - LOG_USER("'%s' watchpoint %d set at " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)", + LOG_USER("'%s' watchpoint %" PRIu32 " set at " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)", wp->rw == WPT_READ ? "read" : wp->rw == WPT_WRITE ? "write" : wp->rw == WPT_ACCESS ? "access" : "?", wp->unique_id, wp->address, wp->length, wp_num); @@ -1252,7 +1252,7 @@ static int unset_watchpoint(struct target *t, struct watchpoint *wp) debug_reg_list[wp_num].bp_value = 0; wp->is_set = false; - LOG_USER("'%s' watchpoint %d removed from " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)", + LOG_USER("'%s' watchpoint %" PRIu32 " removed from " TARGET_ADDR_FMT " with length %" PRIu32 " (hwreg=%d)", wp->rw == WPT_READ ? "read" : wp->rw == WPT_WRITE ? "write" : wp->rw == WPT_ACCESS ? "access" : "?", wp->unique_id, wp->address, wp->length, wp_num); -- |
From: <ge...@op...> - 2025-10-20 14:15:59
|
This is an automated email from Gerrit. "Tomas Vanek <va...@fb...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9174 -- gerrit commit c3656a1b1fd99339e7ace9bb371692dc7e284fe1 Author: Tomas Vanek <va...@fb...> Date: Mon Oct 20 16:01:04 2025 +0200 target/cortex_m: do not expose BASEPRI and FAULTMASK registers on ARMv6M variants (mainly Cortex-M0 and Cortex-M0+) and on ARMv8M baseline (e.g.Cortex-M23). The devices do not have BASEPRI and FAULTMASK functionally implemented and the corresponding register bits are just read as zero, write ignored. ARMv6-M Architecture Reference Manual: Table D3-2 Programmers’ model feature comparison Reduced exception priority management: PRIMASK special-purpose register. No support for changing the priority of configurable exceptions when they are active. Armv8-M Architecture Reference Manual: B3.32 Special-purpose mask registers, PRIMASK, BASEPRI, FAULTMASK, for configurable priority boosting A PE without the Main Extension implements PRIMASK, but does not implement FAULTMASK and BASEPRI. Change-Id: I332cc79718852c0109148817a214a2657960370b Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 9a391fa939..f434dd9c88 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2837,7 +2837,7 @@ int cortex_m_examine(struct target *target) if (armv7m->fp_feature != FPV5_MVE_F && armv7m->fp_feature != FPV5_MVE_I) armv7m->arm.core_cache->reg_list[ARMV8M_VPR].exist = false; - if (cortex_m->core_info->arch == ARM_ARCH_V8M) { + if (armv7m->arm.arch == ARM_ARCH_V8M) { bool cm_has_tz = cortex_m_has_tz(target); bool main_ext = cortex_m_main_extension(target, cpuid); bool baseline = !main_ext; @@ -2858,6 +2858,11 @@ int cortex_m_examine(struct target *target) armv7m->arm.core_cache->reg_list[ARMV8M_PSPLIM_NS].exist = false; armv7m->arm.core_cache->reg_list[ARMV8M_MSPLIM].exist = false; armv7m->arm.core_cache->reg_list[ARMV8M_PSPLIM].exist = false; + + armv7m->arm.core_cache->reg_list[ARMV8M_BASEPRI_S].exist = false; + armv7m->arm.core_cache->reg_list[ARMV8M_FAULTMASK_S].exist = false; + armv7m->arm.core_cache->reg_list[ARMV8M_BASEPRI_NS].exist = false; + armv7m->arm.core_cache->reg_list[ARMV8M_FAULTMASK_NS].exist = false; } else { /* There is no separate regsel for msplim/psplim of ARMV8M mainline with the security extension that would point to correct alias @@ -2867,6 +2872,11 @@ int cortex_m_examine(struct target *target) armv7m->arm.core_cache->reg_list[ARMV8M_PSPLIM].exist = false; } } + + if (baseline) { + armv7m->arm.core_cache->reg_list[ARMV7M_BASEPRI].exist = false; + armv7m->arm.core_cache->reg_list[ARMV7M_FAULTMASK].exist = false; + } } else { /* Security extension and stack limit checking introduced in ARMV8M */ for (size_t idx = ARMV8M_TZ_FIRST_REG; idx <= ARMV8M_TZ_LAST_REG; idx++) @@ -2874,6 +2884,11 @@ int cortex_m_examine(struct target *target) armv7m->arm.core_cache->reg_list[ARMV8M_MSPLIM].exist = false; armv7m->arm.core_cache->reg_list[ARMV8M_PSPLIM].exist = false; + + if (armv7m->arm.arch == ARM_ARCH_V6M) { + armv7m->arm.core_cache->reg_list[ARMV7M_BASEPRI].exist = false; + armv7m->arm.core_cache->reg_list[ARMV7M_FAULTMASK].exist = false; + } } if (!armv7m->is_hla_target) { -- |
From: Neil S. <nl...@ya...> - 2025-10-19 23:15:48
|
Sorry, hit send too soon. Hello, I've noticed that a number of JTAG drivers insert a transition to TAP_IRPAUSE or TAP_DRPAUSE in their _execute_scan functions. The OpenJTAG, armjtagew, buspirate, usbprog, and vsllink all do this. Other drivers such as ftdi bypass the pause state in certain conditions. I believe the reason behind it is to leave the JTAG state machine in a stable state between operations. Removing the mandatory pause for long operations can give a non-trivial performance boost. Is there any other reason to insert the pause state I'm not aware of? Neil Shipp. On Sunday, October 19, 2025 at 03:55:47 PM PDT, Neil Shipp <nl...@ya...> wrote: |
From: Neil S. <nl...@ya...> - 2025-10-19 22:56:03
|
From: Antonio B. <bor...@gm...> - 2025-10-18 06:58:10
|
On Sat, Oct 18, 2025 at 7:38 AM Agnelo Dcosta <ag...@qt...> wrote: > > Thanks for your response, Antonio and Tommy > > > Can the driver be upstream in the OpenOCD code directly? > > What's the license of the driver's code? > > Yes, The EUD Source code is available at https://github.com/quic/eud under licenses GPL-2.0 OR BSD-3 > > We did deliberate internally some time ago, regarding upstreaming the Code into OpenOCD directly. > The EUD library, however, is used by multiple other tools and utilities which is why we decided that EUD code should exist as a separate independent entity. > If submodule support is being deprecated, we are ok to switch to link time external library mode - in fact that is how we had originally done it. > Just to be certain, we should have a configure option like "--enable-external-eud" isn't it? Cool! There are helpers in configure.ac so you don't need to explicitly add the option. The library should be packaged within "pkg-config" to be easily used in the configuration script. Probably the closest match is by looking at LINUXGPIOD.It's a driver that has an external dependency from the library 'libgpiod'. There is some extra code due to incompatibility between version 1 and 2 of the library that you should ignore, that's easy to spot. Just search case-insensitive for the string 'gpiod' in configure.ac and you get the 6 places to update (I suppose you don't need to enable bitbanging). Regards Antonio |
From: <ge...@op...> - 2025-10-17 18:53:23
|
This is an automated email from Gerrit. "Name of user not set <sea...@se...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9173 -- gerrit commit 0e621d0241a73df46213ae8ae0b5d0689fa8af8c Author: Sean Anderson <sea...@li...> Date: Fri Oct 17 14:51:31 2025 -0400 semihosting: Check for overflow in FLEN on 32-bit systems When semihosting 32-bit systems, the return value of FLEN will be stored in a 32-bit integer. To prevent wraparound, return -1 and set EOVERFLOW. This matches the behavior of stat(2). Signed-off-by: Sean Anderson <sea...@li...> Change-Id: Id4577b70bf49ea2b2bc301d9f52db719f88bfa9f diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 5f8ab1082c..6303950468 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -691,11 +691,15 @@ int semihosting_common(struct target *target) semihosting->result = fstat(fd, &buf); if (semihosting->result == -1) { semihosting->sys_errno = errno; - LOG_DEBUG("fstat(%d)=%" PRId64, fd, semihosting->result); - break; + } else if (semihosting->word_size_bytes == 4 && + buf.st_size > 0x7fffffff) { + semihosting->result = -1; + semihosting->sys_errno = EOVERFLOW; + } else { + semihosting->result = buf.st_size; } LOG_DEBUG("fstat(%d)=%" PRId64, fd, semihosting->result); - semihosting->result = buf.st_size; + break; } break; -- |
From: Antonio C. <cub...@us...> - 2025-10-17 16:18:42
|
My edited stm32f4x.cfg Attachments: - [stm32f4x.cfg](https://sourceforge.net/p/openocd/tickets/_discuss/thread/3519208445/bd92/attachment/stm32f4x.cfg) (4.4 kB; application/octet-stream) --- **[tickets:#461] stm32f4x.cfg Requested Speed Too High** **Status:** new **Milestone:** 0.12.0 **Created:** Fri Oct 17, 2025 04:15 PM UTC by Antonio Chiu **Last Updated:** Fri Oct 17, 2025 04:15 PM UTC **Owner:** nobody **Attachments:** - [stm32f4x.cfg Requested Speed Too High.rtf](https://sourceforge.net/p/openocd/tickets/461/attachment/stm32f4x.cfg%20Requested%20Speed%20Too%20High.rtf) (50.0 kB; application/msword) Tested on NUCLEO-F401RE (stm32f401re). It has the slowest Fcpu (adapter speed) in the STM32F4 series. It seems that the original adapter speed for reset-init and reset-start is too high for my board. I've reduced the speed to get rid of the errors. Technically this should work on all other STM32F4 boards as they all have higher Fcpu. --- Sent from sourceforge.net because ope...@li... is subscribed to https://sourceforge.net/p/openocd/tickets/ To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/openocd/admin/tickets/options. Or, if this is a mailing list, you can unsubscribe from the mailing list. |
From: Antonio C. <cub...@us...> - 2025-10-17 16:15:57
|
--- **[tickets:#461] stm32f4x.cfg Requested Speed Too High** **Status:** new **Milestone:** 0.12.0 **Created:** Fri Oct 17, 2025 04:15 PM UTC by Antonio Chiu **Last Updated:** Fri Oct 17, 2025 04:15 PM UTC **Owner:** nobody **Attachments:** - [stm32f4x.cfg Requested Speed Too High.rtf](https://sourceforge.net/p/openocd/tickets/461/attachment/stm32f4x.cfg%20Requested%20Speed%20Too%20High.rtf) (50.0 kB; application/msword) Tested on NUCLEO-F401RE (stm32f401re). It has the slowest Fcpu (adapter speed) in the STM32F4 series. It seems that the original adapter speed for reset-init and reset-start is too high for my board. I've reduced the speed to get rid of the errors. Technically this should work on all other STM32F4 boards as they all have higher Fcpu. --- Sent from sourceforge.net because ope...@li... is subscribed to https://sourceforge.net/p/openocd/tickets/ To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/openocd/admin/tickets/options. Or, if this is a mailing list, you can unsubscribe from the mailing list. |
From: Antonio B. <bor...@gm...> - 2025-10-17 13:57:40
|
Waiting for confirmation from Angelo, I think it would be better to not add a new git submodule to OpenOCD but to build and distribute eud as a library. Then some glue code in OpenOCD will use the library, if present at build; similarly as libjaylink. Antonio On Fri, 17 Oct 2025, 10:44 Tommy Murphy, <tom...@ho...> wrote: > Is this the relevant source code? > > - https://github.com/quic/eud > > If so, then it's GPL v2.0 according to this: > > - https://github.com/quic/eud?tab=readme-ov-file#license > > ------------------------------ > *From:* Antonio Borneo <bor...@gm...> > *Sent:* Friday, October 17, 2025 8:25:25 AM > *To:* Agnelo Dcosta <ag...@qt...> > *Cc:* Ashi Gupta <as...@qt...>; openocd-devel < > ope...@li...> > *Subject:* Re: ERROR:EMBEDDED_FILENAME: for changes in configure.ac > > > > On Fri, 17 Oct 2025, 07:17 Agnelo Dcosta, <ag...@qt...> > wrote: > > Thoughts on this anyone? > Let me know if any more information/detail is required. > > Thanks, > Agnelo > > > ------------------------------ > *From:* Agnelo Dcosta (QUIC) <qui...@qu...> > *Sent:* Thursday, October 9, 2025 5:10 PM > *To:* openocd-devel <ope...@li...> > *Cc:* Ashi Gupta <as...@qt...> > *Subject:* ERROR:EMBEDDED_FILENAME: for changes in configure.ac > > Hi. > > I am trying to add support for a new debug adapter called EUD(Embedded USB > Debug) which is inbuilt into Qualcomm chipsets. > I added the following lines to the <openocd-root-folder>/configure.ac > > *-----------------------x------------------------x-------------------------* > *AS_IF([test "x$enable_eud" != "xno"], [* > * AS_IF([test -f "$srcdir/src/jtag/drivers/eud/configure.ac > <http://configure.ac>"], [* > * AX_CONFIG_SUBDIR_OPTION([src/jtag/drivers/eud], > [--enable-subproject-build])* > * ], [* > * AC_MSG_ERROR([Internal eud not found, run either 'git submodule init' > and 'git submodule update' or disable eud with --disable-eud.])* > * ])* > *])* > > *-----------------------x------------------------x-------------------------* > > > Running tools/checkpatch.sh on the patch throws up following error > > *-----------------------x------------------------x-------------------------* > ERROR:EMBEDDED_FILENAME: It's generally not useful to have the filename in > the file > #720: FILE: configure.ac:720: > + AS_IF([test -f "$srcdir/src/jtag/drivers/eud/configure.ac"], [ > > *-----------------------x------------------------x-------------------------* > > On line configure.ac:720, the "configure.ac*" *refers to a different > configure.ac file under directory src/jtag/drivers/eud. > Is there some way to get around this error? > > > Hi, > > Checkpatch is not bulletproof and sometimes it screams for nothing. > In the file HACKING is reported how to silent it in specific cases like > this, by adding in the commit message the line > Checkpatch-ignore: EMBEDDED_FILENAME > > In OpenOCD we are going to get rid of submodules and we have deprecated > all of them. > What's the value of adding a new one? > Can the driver be upstream in the OpenOCD code directly? > What's the license of the driver's code? Remember that it should be > compatible with the GPLv2 of OpenOCD, either if embedded, or as submodule > or as link-time external library. > > Regards > Antonio > > > |
From: Tommy M. <tom...@ho...> - 2025-10-17 08:44:22
|
Is this the relevant source code? - https://github.com/quic/eud If so, then it's GPL v2.0 according to this: - https://github.com/quic/eud?tab=readme-ov-file#license ________________________________ From: Antonio Borneo <bor...@gm...> Sent: Friday, October 17, 2025 8:25:25 AM To: Agnelo Dcosta <ag...@qt...> Cc: Ashi Gupta <as...@qt...>; openocd-devel <ope...@li...> Subject: Re: ERROR:EMBEDDED_FILENAME: for changes in configure.ac On Fri, 17 Oct 2025, 07:17 Agnelo Dcosta, <ag...@qt...<mailto:ag...@qt...>> wrote: Thoughts on this anyone? Let me know if any more information/detail is required. Thanks, Agnelo ________________________________ From: Agnelo Dcosta (QUIC) <qui...@qu...<mailto:qui...@qu...>> Sent: Thursday, October 9, 2025 5:10 PM To: openocd-devel <ope...@li...<mailto:ope...@li...>> Cc: Ashi Gupta <as...@qt...<mailto:as...@qt...>> Subject: ERROR:EMBEDDED_FILENAME: for changes in configure.ac<http://configure.ac> Hi. I am trying to add support for a new debug adapter called EUD(Embedded USB Debug) which is inbuilt into Qualcomm chipsets. I added the following lines to the <openocd-root-folder>/configure.ac<http://configure.ac> -----------------------x------------------------x------------------------- AS_IF([test "x$enable_eud" != "xno"], [ AS_IF([test -f "$srcdir/src/jtag/drivers/eud/configure.ac<http://configure.ac>"], [ AX_CONFIG_SUBDIR_OPTION([src/jtag/drivers/eud], [--enable-subproject-build]) ], [ AC_MSG_ERROR([Internal eud not found, run either 'git submodule init' and 'git submodule update' or disable eud with --disable-eud.]) ]) ]) -----------------------x------------------------x------------------------- Running tools/checkpatch.sh on the patch throws up following error -----------------------x------------------------x------------------------- ERROR:EMBEDDED_FILENAME: It's generally not useful to have the filename in the file #720: FILE: configure.ac:720<http://configure.ac:720>: + AS_IF([test -f "$srcdir/src/jtag/drivers/eud/configure.ac<http://configure.ac>"], [ -----------------------x------------------------x------------------------- On line configure.ac:720<http://configure.ac:720>, the "configure.ac<http://configure.ac>" refers to a different configure.ac<http://configure.ac> file under directory src/jtag/drivers/eud. Is there some way to get around this error? Hi, Checkpatch is not bulletproof and sometimes it screams for nothing. In the file HACKING is reported how to silent it in specific cases like this, by adding in the commit message the line Checkpatch-ignore: EMBEDDED_FILENAME In OpenOCD we are going to get rid of submodules and we have deprecated all of them. What's the value of adding a new one? Can the driver be upstream in the OpenOCD code directly? What's the license of the driver's code? Remember that it should be compatible with the GPLv2 of OpenOCD, either if embedded, or as submodule or as link-time external library. Regards Antonio |
From: Antonio B. <bor...@gm...> - 2025-10-17 07:25:48
|
On Fri, 17 Oct 2025, 07:17 Agnelo Dcosta, <ag...@qt...> wrote: > Thoughts on this anyone? > Let me know if any more information/detail is required. > > Thanks, > Agnelo > > > ------------------------------ > *From:* Agnelo Dcosta (QUIC) <qui...@qu...> > *Sent:* Thursday, October 9, 2025 5:10 PM > *To:* openocd-devel <ope...@li...> > *Cc:* Ashi Gupta <as...@qt...> > *Subject:* ERROR:EMBEDDED_FILENAME: for changes in configure.ac > > Hi. > > I am trying to add support for a new debug adapter called EUD(Embedded USB > Debug) which is inbuilt into Qualcomm chipsets. > I added the following lines to the <openocd-root-folder>/configure.ac > > *-----------------------x------------------------x-------------------------* > *AS_IF([test "x$enable_eud" != "xno"], [* > * AS_IF([test -f "$srcdir/src/jtag/drivers/eud/configure.ac > <http://configure.ac>"], [* > * AX_CONFIG_SUBDIR_OPTION([src/jtag/drivers/eud], > [--enable-subproject-build])* > * ], [* > * AC_MSG_ERROR([Internal eud not found, run either 'git submodule init' > and 'git submodule update' or disable eud with --disable-eud.])* > * ])* > *])* > > *-----------------------x------------------------x-------------------------* > > > Running tools/checkpatch.sh on the patch throws up following error > > *-----------------------x------------------------x-------------------------* > ERROR:EMBEDDED_FILENAME: It's generally not useful to have the filename in > the file > #720: FILE: configure.ac:720: > + AS_IF([test -f "$srcdir/src/jtag/drivers/eud/configure.ac"], [ > > *-----------------------x------------------------x-------------------------* > > On line configure.ac:720, the "configure.ac*" *refers to a different > configure.ac file under directory src/jtag/drivers/eud. > Is there some way to get around this error? > Hi, Checkpatch is not bulletproof and sometimes it screams for nothing. In the file HACKING is reported how to silent it in specific cases like this, by adding in the commit message the line Checkpatch-ignore: EMBEDDED_FILENAME In OpenOCD we are going to get rid of submodules and we have deprecated all of them. What's the value of adding a new one? Can the driver be upstream in the OpenOCD code directly? What's the license of the driver's code? Remember that it should be compatible with the GPLv2 of OpenOCD, either if embedded, or as submodule or as link-time external library. Regards Antonio > |
From: <ge...@op...> - 2025-10-15 10:52:52
|
This is an automated email from Gerrit. "P. Frost <ma...@pf...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9026 -- gerrit commit fe3f8f3d7690366532214802e73ef52dc32c6d81 Author: Peter Frost <ma...@pf...> Date: Wed Oct 15 11:43:11 2025 +0100 STM32L: Automatically execute an OBL reset after locking or unlocking stm32lx devices This aligns it with the behaviour of the stm32l4x driver, which is more user-friendly as the device does not need to be manually power-cycled to apply the protection Change-Id: I3382bb245f03463fac7cbad45572eaa038c3e953 Signed-off-by: Peter Frost <ma...@pf...> diff --git a/src/flash/nor/stm32lx.c b/src/flash/nor/stm32lx.c index 2c7563e95a..bc8561b584 100644 --- a/src/flash/nor/stm32lx.c +++ b/src/flash/nor/stm32lx.c @@ -267,6 +267,26 @@ static const struct stm32lx_part_info stm32lx_parts[] = { }, }; +static int stm32lx_obl_launch(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; + int retval; + + /* This will fail as the target gets immediately rebooted */ + target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR, + FLASH_PECR__OBL_LAUNCH); + + size_t tries = 10; + do { + target_halt(target); + retval = target_poll(target); + } while (--tries > 0 && + (retval != ERROR_OK || target->state != TARGET_HALTED)); + + return tries ? ERROR_OK : ERROR_FAIL; +} + /* flash bank stm32lx <base> <size> 0 0 <target#> */ FLASH_BANK_COMMAND_HANDLER(stm32lx_flash_bank_command) @@ -327,10 +347,14 @@ COMMAND_HANDLER(stm32lx_handle_lock_command) retval = stm32lx_lock(bank); if (retval == ERROR_OK) - command_print(CMD, "STM32Lx locked, takes effect after power cycle."); + command_print(CMD, "STM32Lx locked"); else command_print(CMD, "STM32Lx lock failed"); + retval = stm32lx_obl_launch(bank); + if (retval != ERROR_OK) + return retval; + return retval; } @@ -347,10 +371,14 @@ COMMAND_HANDLER(stm32lx_handle_unlock_command) retval = stm32lx_unlock(bank); if (retval == ERROR_OK) - command_print(CMD, "STM32Lx unlocked, takes effect after power cycle."); + command_print(CMD, "STM32Lx unlocked"); else command_print(CMD, "STM32Lx unlock failed"); + retval = stm32lx_obl_launch(bank); + if (retval != ERROR_OK) + return retval; + return retval; } @@ -1234,26 +1262,6 @@ static int stm32lx_wait_until_bsy_clear_timeout(struct flash_bank *bank, int tim return retval; } -static int stm32lx_obl_launch(struct flash_bank *bank) -{ - struct target *target = bank->target; - struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; - int retval; - - /* This will fail as the target gets immediately rebooted */ - target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR, - FLASH_PECR__OBL_LAUNCH); - - size_t tries = 10; - do { - target_halt(target); - retval = target_poll(target); - } while (--tries > 0 && - (retval != ERROR_OK || target->state != TARGET_HALTED)); - - return tries ? ERROR_OK : ERROR_FAIL; -} - static int stm32lx_lock(struct flash_bank *bank) { int retval; -- |
From: <ge...@op...> - 2025-10-14 16:24:37
|
This is an automated email from Gerrit. "Jonathan Steinert <ha...@ku...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9172 -- gerrit commit fcad6ab5142d176061861d6a40b93abdcc633e87 Author: Jonathan Steinert <ha...@ku...> Date: Tue Oct 14 09:06:33 2025 -0700 xmc4xxx: Correct some flash sector layouts I think this may have been a typo/thinko from first implementation, but for the 4200 the layout is 8 16KB chunks and then 1 128KB chunk. We were previously only writing 240KB Signed-off-by: ha...@ku... CC: ka...@tw... Change-Id: Ic3cff75ba21f6bc6ac440dfb30e24c328c7cd47c diff --git a/src/flash/nor/xmc4xxx.c b/src/flash/nor/xmc4xxx.c index 54fd5a5867..bf41cc7eb1 100644 --- a/src/flash/nor/xmc4xxx.c +++ b/src/flash/nor/xmc4xxx.c @@ -231,12 +231,12 @@ struct xmc4xxx_command_seq { }; /* Sector capacities. See section 8 of xmc4x00_rm */ -static const unsigned int sector_capacity_8[8] = { - 16, 16, 16, 16, 16, 16, 16, 128 +static const unsigned int sector_capacity_9[9] = { + 16, 16, 16, 16, 16, 16, 16, 16, 128 }; -static const unsigned int sector_capacity_9[9] = { - 16, 16, 16, 16, 16, 16, 16, 128, 256 +static const unsigned int sector_capacity_10[10] = { + 16, 16, 16, 16, 16, 16, 16, 16, 128, 256 }; static const unsigned int sector_capacity_12[12] = { @@ -272,12 +272,12 @@ static int xmc4xxx_load_bank_layout(struct flash_bank *bank) LOG_DEBUG("%u sectors", bank->num_sectors); switch (bank->num_sectors) { - case 8: - capacity = sector_capacity_8; - break; case 9: capacity = sector_capacity_9; break; + case 10: + capacity = sector_capacity_10; + break; case 12: capacity = sector_capacity_12; break; @@ -361,11 +361,11 @@ static int xmc4xxx_probe(struct flash_bank *bank) * we understand the type of controller we're dealing with */ switch (flash_id) { case FLASH_ID_XMC4100_4200: - bank->num_sectors = 8; + bank->num_sectors = 9; LOG_DEBUG("XMC4xxx: XMC4100/4200 detected."); break; case FLASH_ID_XMC4400: - bank->num_sectors = 9; + bank->num_sectors = 10; LOG_DEBUG("XMC4xxx: XMC4400 detected."); break; case FLASH_ID_XMC4500: -- |
From: <ge...@op...> - 2025-10-14 13:58:03
|
This is an automated email from Gerrit. "Tomas Vanek <va...@fb...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9170 -- gerrit commit 6de16f01199b9ac552614f36502d0f9cceda7f3a Author: Tomas Vanek <va...@fb...> Date: Mon Oct 13 18:09:27 2025 +0200 target/riscv: implement get_capab() Add support for getting optional capabilities. Change-Id: I8bef0532139f4f9b129c7d56f802347a52c4ee90 Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 9da9684e4e..f2713bf096 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -67,6 +67,7 @@ static int register_write_direct(struct target *target, enum gdb_regno number, static int riscv013_access_memory(struct target *target, const struct riscv_mem_access_args args); static bool riscv013_get_impebreak(const struct target *target); static unsigned int riscv013_get_progbufsize(const struct target *target); +static int sba_supports_access(struct target *target, unsigned int size_bytes); enum grouptype { HALT_GROUP, @@ -2246,6 +2247,26 @@ static unsigned int riscv013_data_bits(struct target *target) return 32; } +static unsigned int riscv013_get_capab(struct target *target) +{ + RISCV_INFO(r); + + for (unsigned int i = 0; i < r->num_enabled_mem_access_methods; i++) { + enum riscv_mem_access_method method = r->mem_access_methods[i]; + + if (method == RISCV_MEM_ACCESS_SYSBUS) { + unsigned int bytes = riscv_xlen(target) / 8; + if (sba_supports_access(target, bytes)) { + return TARGET_CAPAB_MEM_READ_WHILE_RUNNING + | TARGET_CAPAB_MEM_WRITE_WHILE_RUNNING + | TARGET_CAPAB_BP_WP_MANIP_AT_ANY_STATE; + } + } + } + + return TARGET_CAPAB_BP_WP_MANIP_AT_ANY_STATE; +} + static COMMAND_HELPER(riscv013_print_info, struct target *target) { RISCV013_INFO(info); @@ -2874,6 +2895,7 @@ static int init_target(struct command_context *cmd_ctx, generic_info->get_dmi_address = &riscv013_get_dmi_address; generic_info->access_memory = &riscv013_access_memory; generic_info->data_bits = &riscv013_data_bits; + generic_info->get_capab = &riscv013_get_capab; generic_info->print_info = &riscv013_print_info; generic_info->get_impebreak = &riscv013_get_impebreak; generic_info->get_progbufsize = &riscv013_get_progbufsize; diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 7ef875f805..f7e0b4221d 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -5896,6 +5896,16 @@ static unsigned int riscv_data_bits(struct target *target) return riscv_xlen(target); } +static unsigned int riscv_get_capab(struct target *target) +{ + RISCV_INFO(r); + + if (r->get_capab) + return r->get_capab(target); + + return TARGET_CAPAB_BP_WP_MANIP_AT_ANY_STATE; +} + struct target_type riscv_target = { .name = "riscv", @@ -5943,7 +5953,8 @@ struct target_type riscv_target = { .commands = riscv_command_handlers, .address_bits = riscv_xlen_nonconst, - .data_bits = riscv_data_bits + .data_bits = riscv_data_bits, + .get_capab = riscv_get_capab, }; /*** RISC-V Interface ***/ diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h index 2a0a9b95f0..b2768352a4 100644 --- a/src/target/riscv/riscv.h +++ b/src/target/riscv/riscv.h @@ -306,6 +306,7 @@ struct riscv_info { int (*access_memory)(struct target *target, const struct riscv_mem_access_args args); unsigned int (*data_bits)(struct target *target); + unsigned int (*get_capab)(struct target *target); COMMAND_HELPER((*print_info), struct target *target); -- |
From: <ge...@op...> - 2025-10-14 13:58:02
|
This is an automated email from Gerrit. "Tomas Vanek <va...@fb...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9168 -- gerrit commit a5b21ec611d727f6b6bdc526a0c5ef392c6f652d Author: Tomas Vanek <va...@fb...> Date: Mon Oct 13 18:35:37 2025 +0200 target/esirisc_trace: rename macro conflicting with bits.h The esirisc_trace.c uses macro BIT_MASK(), same name as a macro from helper/bits.h Rename the former to allow including bits.h helper in target.h Change-Id: I0cc6a58e5aff3f48fa9a79a99bd28124f334c4e2 Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/target/esirisc_trace.c b/src/target/esirisc_trace.c index 2dc08e5d2d..565511471f 100644 --- a/src/target/esirisc_trace.c +++ b/src/target/esirisc_trace.c @@ -18,7 +18,7 @@ #include "esirisc.h" -#define BIT_MASK(x) ((1 << (x)) - 1) +#define BITS_MASK(x) ((1 << (x)) - 1) /* Control Fields */ #define CONTROL_ST (1<<0) /* Start */ @@ -483,7 +483,7 @@ static int esirisc_trace_analyze_simple(struct command_invocation *cmd, uint8_t struct target *target = get_current_target(cmd->ctx); struct esirisc_common *esirisc = target_to_esirisc(target); struct esirisc_trace *trace_info = &esirisc->trace_info; - const uint32_t end_of_trace = BIT_MASK(trace_info->pc_bits) << 1; + const uint32_t end_of_trace = BITS_MASK(trace_info->pc_bits) << 1; const uint32_t num_bits = size * 8; int retval; -- |
From: <ge...@op...> - 2025-10-14 13:58:02
|
This is an automated email from Gerrit. "Tomas Vanek <va...@fb...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9171 -- gerrit commit db04cb87afc20d5f18be2cd071652af027c0d84b Author: Tomas Vanek <va...@fb...> Date: Tue Oct 14 15:29:55 2025 +0200 target/riscv: return ERROR_TARGET_NOT_HALTED instead of ERROR_FAIL where appropriate. Change-Id: I1881c0c6c437355007c3844556489162666023dc Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index f2713bf096..2c55334947 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -2344,7 +2344,7 @@ static int prep_for_vector_access(struct target *target, if (target->state != TARGET_HALTED) { LOG_TARGET_ERROR(target, "Unable to access vector register: target not halted"); - return ERROR_FAIL; + return ERROR_TARGET_NOT_HALTED; } if (prep_for_register_access(target, orig_mstatus, GDB_REGNO_VL) != ERROR_OK) return ERROR_FAIL; @@ -5498,7 +5498,7 @@ static int riscv013_step_or_resume_current_hart(struct target *target, { if (target->state != TARGET_HALTED) { LOG_TARGET_ERROR(target, "Hart is not halted!"); - return ERROR_FAIL; + return ERROR_TARGET_NOT_HALTED; } LOG_TARGET_DEBUG(target, "resuming (operation=%s)", diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index f7e0b4221d..d7d5b488bb 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -5425,7 +5425,7 @@ COMMAND_HANDLER(riscv_exec_progbuf) if (target->state != TARGET_HALTED) { LOG_TARGET_ERROR(target, "exec_progbuf: Can't execute " "program buffer, target not halted."); - return ERROR_FAIL; + return ERROR_TARGET_NOT_HALTED; } if (riscv_progbuf_size(target) == 0) { @@ -6050,7 +6050,7 @@ static int riscv_step_rtos_hart(struct target *target) if (target->state != TARGET_HALTED) { LOG_TARGET_ERROR(target, "Hart isn't halted before single step!"); - return ERROR_FAIL; + return ERROR_TARGET_NOT_HALTED; } r->on_step(target); if (r->step_current_hart(target) != ERROR_OK) @@ -6240,7 +6240,7 @@ int riscv_enumerate_triggers(struct target *target) if (target->state != TARGET_HALTED) { LOG_TARGET_ERROR(target, "Unable to enumerate triggers: target not halted."); - return ERROR_FAIL; + return ERROR_TARGET_NOT_HALTED; } riscv_reg_t orig_tselect; -- |
From: <ge...@op...> - 2025-10-14 13:57:57
|
This is an automated email from Gerrit. "Tomas Vanek <va...@fb...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9169 -- gerrit commit 01b6b95787321440f5a9632cded04ba0535f5290 Author: Tomas Vanek <va...@fb...> Date: Mon Oct 13 15:39:05 2025 +0200 target: introduce target capability bits Add target_get_capab() call to identify which optional capabilities the target supports. For the beginning define bits for memory read/write while running and HW breakpoint/watchpoint manipulation at any state. Add simple usage in cortex_m.c Change-Id: I1a28f3707dfff9a2424090bb125990c7ea9a0387 Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index 42e9572602..b172d1bcd4 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -3101,6 +3101,13 @@ static int cortex_m_target_create(struct target *target) return ERROR_OK; } +static unsigned int cortex_m_get_capab(struct target *target) +{ + return TARGET_CAPAB_MEM_READ_WHILE_RUNNING + | TARGET_CAPAB_MEM_WRITE_WHILE_RUNNING + | TARGET_CAPAB_BP_WP_MANIP_AT_ANY_STATE; +} + /*--------------------------------------------------------------------------*/ static int cortex_m_verify_pointer(struct command_invocation *cmd, @@ -3405,4 +3412,6 @@ struct target_type cortexm_target = { .deinit_target = cortex_m_deinit_target, .profiling = cortex_m_profiling, + + .get_capab = cortex_m_get_capab, }; diff --git a/src/target/target.c b/src/target/target.c index bdf0ff244d..5f1c85c3a5 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1474,6 +1474,13 @@ unsigned int target_data_bits(struct target *target) return 32; } +unsigned int target_get_capab(struct target *target) +{ + if (target->type->get_capab) + return target->type->get_capab(target); + return 0; +} + static int target_profiling(struct target *target, uint32_t *samples, uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds) { diff --git a/src/target/target.h b/src/target/target.h index 6efcc7677b..b1fc0001d8 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -20,6 +20,7 @@ #ifndef OPENOCD_TARGET_TARGET_H #define OPENOCD_TARGET_TARGET_H +#include <helper/bits.h> #include <helper/list.h> #include "helper/replacements.h" #include "helper/system.h" @@ -85,6 +86,10 @@ enum target_endianness { TARGET_BIG_ENDIAN = 1, TARGET_LITTLE_ENDIAN = 2 }; +#define TARGET_CAPAB_MEM_READ_WHILE_RUNNING BIT(0) +#define TARGET_CAPAB_MEM_WRITE_WHILE_RUNNING BIT(1) +#define TARGET_CAPAB_BP_WP_MANIP_AT_ANY_STATE BIT(2) + struct working_area { target_addr_t address; uint32_t size; @@ -690,6 +695,13 @@ unsigned int target_address_bits(struct target *target); */ unsigned int target_data_bits(struct target *target); +/** + * Return target capabilities as TARGET_CAPAB_ bits. + * + * This routine is a wrapper for target->type->get_capab + */ +unsigned int target_get_capab(struct target *target); + /** Return the *name* of this targets current state */ const char *target_state_name(const struct target *target); diff --git a/src/target/target_type.h b/src/target/target_type.h index ccbe03a476..6b1443c6b7 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -305,6 +305,10 @@ struct target_type { * will typically be 32 for 32-bit targets, and 64 for 64-bit targets. If * not implemented, it's assumed to be 32. */ unsigned int (*data_bits)(struct target *target); + + /* Return target capabilities as TARGET_CAPAB_ bits. + * Assume zero return (no optional capabilities) if not implemented */ + unsigned int (*get_capab)(struct target *target); }; // Keep in alphabetic order this list of targets -- |
From: <ge...@op...> - 2025-10-13 14:09:32
|
This is an automated email from Gerrit. "Name of user not set <din...@mi...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9025 -- gerrit commit 04da9013f3457813bb2c1e33a719edb295a26015 Author: DineshArasu-Microchip <din...@mi...> Date: Mon Oct 13 19:32:51 2025 +0530 Adding WBZ451, WBZ450, PIC32WM_BZ and WBZ351 microchip flash drivers support Change-Id: I491341d2c2d50d4976ea454a4f7e477033db92eb Signed-off-by: Dinesh Arasu <din...@mi...> Signed-off-by: DineshArasu-Microchip <din...@mi...> diff --git a/doc/openocd.texi b/doc/openocd.texi index 7f7c8892fe..b3493b5795 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -7064,6 +7064,32 @@ the appropriate at91sam7 target. @end deffn @end deffn +@anchor{pic32cx_bz} +@deffn {Flash Driver} {pic32cx_bz} +@cindex wbz451 +All members of the WBZ45x, PIC32CX_BZ2, PIC32WM_BZ6 microcontroller +families from Microchip include internal flash and use ARM's Cortex-M4 core. + +This driver supports: +@itemize +@item Row programming (1024 bytes per row) +@item Page erase (1024 bytes per row) +@item Skipping @code{0xFF}-only regions for faster flashing +@end itemize + +The driver is located at: @file{src/flash/nor/pic32cx_bz.c}. + +@example +flash bank $_FLASHNAME pic32cx_bz 0x01000000 0x00100000 0 0 $_TARGETNAME +@end example + +@deffn {Command} {pic32cx_bz dsu_reset_deassert} +This command releases internal reset held by DSU +and prepares reset vector catch in case of reset halt. +Command is used internally in event reset-deassert-post. +@end deffn +@end deffn + @deffn {Flash Driver} {avr} The AVR 8-bit microcontrollers from Atmel integrate flash memory. @emph{The current implementation is incomplete.} diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index f408559004..f64df62ff9 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -83,7 +83,8 @@ NOR_DRIVERS = \ %D%/w600.c \ %D%/xcf.c \ %D%/xmc1xxx.c \ - %D%/xmc4xxx.c + %D%/xmc4xxx.c \ + %D%/pic32cx_bz.c NORHEADERS = \ %D%/artery.h \ diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index 2bd2043633..bd467c4e5e 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -313,5 +313,6 @@ extern const struct flash_driver w600_flash; extern const struct flash_driver xcf_flash; extern const struct flash_driver xmc1xxx_flash; extern const struct flash_driver xmc4xxx_flash; +extern const struct flash_driver pic32cx_bz_flash; #endif /* OPENOCD_FLASH_NOR_DRIVER_H */ diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index 6b0def6810..d4e3068e8a 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -92,6 +92,7 @@ static const struct flash_driver * const flash_drivers[] = { &xcf_flash, &xmc1xxx_flash, &xmc4xxx_flash, + &pic32cx_bz_flash, }; const struct flash_driver *flash_driver_find_by_name(const char *name) diff --git a/src/flash/nor/pic32cx_bz.c b/src/flash/nor/pic32cx_bz.c new file mode 100644 index 0000000000..a1748f3bb2 --- /dev/null +++ b/src/flash/nor/pic32cx_bz.c @@ -0,0 +1,570 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/************************************************************************************** + * Copyright (C) 2025 by Microchip Technologies Inc * + * Author: Dinesh Arasu - din...@mi... * + * * + * Description: Flash driver for WBZ and PIC32CX_BZx Microchip Curiosity Board * + **************************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "imp.h" +#include "helper/binarybuffer.h" +#include <helper/time_support.h> +#include <jtag/jtag.h> +#include <target/cortex_m.h> +#include <stdbool.h> +#include <string.h> +#include <target/target_type.h> +#include <stdlib.h> +#include <inttypes.h> + +#define DSU_DID_REG 0x41000018U + +/* Generic NVM operation bits */ +#define NVMCON_NVMWREN (1 << 14) +#define NVMCON_NVMWR (1 << 15) +#define NVMCON_OP_WORD_PROG 0x4001 +#define NVMCON_OP_ROW_PROG 0x4003 +#define NVMCON_OP_PAGE_ERASE 0x4004 +#define NVMCON_OP_PBC 0x4007 +#define NVMCON_OP_MASK 0x7FFF + +/* RAM staging buffer address used across drivers */ +#define RAM_BUF_ADDR 0x20000000U + +/* default row size used by these parts */ +#define DEFAULT_ROW_SIZE 1024U + +/* NVMLBWP unlock key used in originals */ +#define NVMLBWP_UNLOCK_KEY 0x80000000U + +struct pic32cx_dev { + uint32_t device_id; + const char *name; + uint32_t flash_base; + uint32_t flash_size; + uint32_t row_size; + uint32_t page_size; + uint32_t pac_base; + uint32_t nvmcon; + uint32_t nvmkey; + uint32_t nvmaddr; + uint32_t nvmsrcaddr; + uint32_t nvmdata; + uint32_t nvmconset; + uint32_t nvmconclr; + uint32_t nvmlbwp; + uint32_t nvm_param; + uint32_t nvm_err_mask; +}; + +static const struct pic32cx_dev device_table[] = { + { + .device_id = 0x00009B8F, /* WBZ451 */ + .name = "WBZ451", + .flash_base = 0x01000000U, + .flash_size = 0x00100000U, /* 1 MB */ + .row_size = DEFAULT_ROW_SIZE, + .page_size = DEFAULT_ROW_SIZE, + .pac_base = 0x40000000U, + .nvmcon = 0x44000600U, + .nvmkey = 0x44000620U, + .nvmaddr = 0x44000630U, + .nvmsrcaddr = 0x440006C0U, + .nvmdata = 0x44000640U, + .nvmconset = 0x44000608U, + .nvmconclr = 0x44000604U, + .nvmlbwp = 0x440006F0U, + .nvm_param = 0x44000610U, + .nvm_err_mask = 0x3F00U + }, + { + .device_id = 0x00009B0B, /* WBZ450 */ + .name = "WBZ450", + .flash_base = 0x01000000U, + .flash_size = 0x00100000U, /* 1 MB */ + .row_size = DEFAULT_ROW_SIZE, + .page_size = DEFAULT_ROW_SIZE, + .pac_base = 0x40000000U, + .nvmcon = 0x44000600U, + .nvmkey = 0x44000620U, + .nvmaddr = 0x44000630U, + .nvmsrcaddr = 0x440006C0U, + .nvmdata = 0x44000640U, + .nvmconset = 0x44000608U, + .nvmconclr = 0x44000604U, + .nvmlbwp = 0x440006F0U, + .nvm_param = 0x44000610U, + .nvm_err_mask = 0x3F00U + }, + { + .device_id = 0x00009E03, /* WBZ351 */ + .name = "WBZ351", + .flash_base = 0x01000000U, + .flash_size = 0x00080000U, /* 512 KB */ + .row_size = DEFAULT_ROW_SIZE, + .page_size = DEFAULT_ROW_SIZE, + .pac_base = 0x40000000U, + .nvmcon = 0x44000600U, + .nvmkey = 0x44000620U, + .nvmaddr = 0x44000630U, + .nvmsrcaddr = 0x440006C0U, + .nvmdata = 0x44000640U, + .nvmconset = 0x44000608U, + .nvmconclr = 0x44000604U, + .nvmlbwp = 0x440006F0U, + .nvm_param = 0x44000610U, + .nvm_err_mask = 0x3F00U + }, + { + .device_id = 0x0001A800, /* PIC32WM_BZ6204 */ + .name = "PIC32WM", + .flash_base = 0x01000000U, + .flash_size = 0x00200000U, /* 2 MB */ + .row_size = DEFAULT_ROW_SIZE, + .page_size = DEFAULT_ROW_SIZE, + .pac_base = 0x40000000U, + .nvmcon = 0x44000600U, + .nvmkey = 0x44000620U, + .nvmaddr = 0x44000630U, + .nvmsrcaddr = 0x440006C0U, + .nvmdata = 0x44000640U, + .nvmconset = 0x44000608U, + .nvmconclr = 0x44000604U, + .nvmlbwp = 0x440006F0U, + .nvm_param = 0x44000610U, + .nvm_err_mask = 0x3F00U + } +}; + +struct pic32cx_priv { + struct target *target; + bool probed; + const struct pic32cx_dev *dev; + uint32_t page_size; + uint32_t num_pages; +}; + +static const struct pic32cx_dev *find_device_by_did(uint32_t did) +{ + for (size_t i = 0; i < ARRAY_SIZE(device_table); ++i) + if (device_table[i].device_id != 0 && device_table[i].device_id == did) + return &device_table[i]; + return NULL; +} + +static const struct pic32cx_dev *find_device_by_name(const char *name) +{ + if (!name) return NULL; + for (size_t i = 0; i < ARRAY_SIZE(device_table); ++i) + if (strstr(name, device_table[i].name) != NULL) + return &device_table[i]; + return NULL; +} + +/* unlock via PAC if locked (same as originals) */ +static int pic32cx_unlock_flash(const struct pic32cx_dev *dev, struct target *t) +{ + uint32_t status; + int res = target_read_u32(t, dev->pac_base + 0x18U, &status); + if (res != ERROR_OK) return res; + + if (status & (1 << 1)) { + LOG_INFO("PAC indicates NVMCTRL is locked. Attempting to unlock..."); + res = target_write_u32(t, dev->pac_base + 0x20U, (1 << 1)); + if (res != ERROR_OK) return res; + } + return target_read_u32(t, dev->pac_base + 0x18U, &status); +} + +/* Generic NVM command issuer derived from wbz451_issue_nvmcmd */ +static int pic32cx_issue_nvmcmd(const struct pic32cx_dev *dev, struct target *t, + uint32_t flash_addr, uint16_t cmd, uint32_t src_addr) +{ + int res; + + /* For boot/alias region operations we must write NVMLBWP */ + if (flash_addr < dev->flash_base) { + if (dev->nvmlbwp) { + res = target_write_u32(t, dev->nvmlbwp, NVMLBWP_UNLOCK_KEY); + if (res != ERROR_OK) return res; + } + } else { + res = pic32cx_unlock_flash(dev, t); + if (res != ERROR_OK) return res; + } + + /* Clear previous error flags */ + if (dev->nvmconclr) { + res = target_write_u32(t, dev->nvmconclr, dev->nvm_err_mask); + if (res != ERROR_OK) return res; + } + + /* Align dest to row */ + flash_addr &= ~(dev->row_size - 1U); + + /* Set NVMSRCADDR if ROW_PROGRAM */ + if (cmd == NVMCON_OP_ROW_PROG && dev->nvmsrcaddr) { + res = target_write_u32(t, dev->nvmsrcaddr, src_addr); + if (res != ERROR_OK) return res; + } + + /* Set NVMADDR */ + res = target_write_u32(t, dev->nvmaddr, flash_addr); + if (res != ERROR_OK) return res; + + /* Set WREN and operation */ + res = target_write_u32(t, dev->nvmcon, NVMCON_NVMWREN | (cmd & NVMCON_OP_MASK)); + if (res != ERROR_OK) return res; + + /* NVMKEY sequence */ + res = target_write_u32(t, dev->nvmkey, 0x00000000U); if (res != ERROR_OK) return res; + res = target_write_u32(t, dev->nvmkey, 0xAA996655U); if (res != ERROR_OK) return res; + res = target_write_u32(t, dev->nvmkey, 0x556699AAU); if (res != ERROR_OK) return res; + + /* Start operation */ + res = target_write_u32(t, dev->nvmconset, NVMCON_NVMWR); + if (res != ERROR_OK) return res; + + /* Wait for NVMWR to clear */ + uint32_t val; + int timeout = 10000; + do { + res = target_read_u32(t, dev->nvmcon, &val); + if (res != ERROR_OK) return res; + if (!--timeout) { + LOG_ERROR("Timeout waiting for NVMWR clear (addr: 0x%08" PRIx32 ", cmd: 0x%X)", flash_addr, cmd); + return ERROR_FAIL; + } + alive_sleep(1); + } while (val & NVMCON_NVMWR); + + if (val & dev->nvm_err_mask) { + LOG_ERROR("NVM error detected (NVMCON=0x%08" PRIx32 ")", val); + return ERROR_FAIL; + } + + /* Clear NVMWREN */ + return target_write_u32(t, dev->nvmconclr, NVMCON_NVMWREN); +} + +/* Probe: uses per-device probe logic (keeps original region checks) */ +static int pic32cx_probe(struct flash_bank *bank) +{ + struct pic32cx_priv *priv = bank->driver_priv; + if (!priv) return ERROR_FAIL; + if (priv->probed) return ERROR_OK; + + struct target *t = bank->target; + uint32_t did = 0; + int res = target_read_u32(t, DSU_DID_REG, &did); + + const struct pic32cx_dev *dev = NULL; + if (res == ERROR_OK) { + dev = find_device_by_did(did); + if (dev) + LOG_INFO("Detected device by DSU DID: %s (DID 0x%08" PRIx32 ")", dev->name, did); + } else { + LOG_WARNING("Failed to read DSU DID at 0x%08" PRIx32 ". Will try name-based detection.", DSU_DID_REG); + } + + /* name fallback */ + if (!dev) + dev = find_device_by_name(bank->name); + + if (!dev) { + LOG_WARNING("No device matched by DID or name. Falling back to WBZ451 defaults."); + dev = &device_table[0]; + } + + priv->dev = dev; + priv->target = t; + + /* Use device-specific probe ranges — reuse logic from original files */ + uint32_t base = bank->base; + uint32_t param = 0; + if (dev->nvm_param) + target_read_u32(t, dev->nvm_param, ¶m); + + /* Apply device-specific mapping (copied/adapted from originals) */ + if ((strcmp(dev->name, "WBZ451") == 0) || (strcmp(dev->name, "WBZ450") == 0)) { + if (base < 0x00005000U) { + priv->page_size = dev->row_size; + priv->num_pages = 20; /* 20 kB BootFlash */ + } else if (base >= 0x00005000U && base < 0x00006000U) { + priv->page_size = dev->row_size; priv->num_pages = 4; + } else if (base >= 0x00006000U && base < 0x00007000U) { + priv->page_size = dev->row_size; priv->num_pages = 4; + } else if (base >= 0x00045000U && base < 0x00047000U) { + priv->page_size = dev->row_size; priv->num_pages = 8; + } else if (base >= dev->flash_base && base < (dev->flash_base + dev->flash_size)) { + priv->page_size = dev->row_size; priv->num_pages = dev->flash_size / dev->row_size; + } else if (bank->base == 0xE000ED10U) { + priv->page_size = dev->row_size; priv->num_pages = 1; + } + } else if ((strcmp(dev->name, "WBZ351") == 0) || (strcmp(dev->name, "WBZ350") == 0)) { + /* mapping from wbz351.c */ + if (base < 0x00010000U) { + priv->page_size = dev->row_size; priv->num_pages = 64; + } else if (bank->base >= 0x00800000U && base < 0x00805000U) { + priv->page_size = dev->row_size; priv->num_pages = 20; + } else if (bank->base >= 0x00805000U && bank->base < 0x00806000U) { + priv->page_size = dev->row_size; priv->num_pages = 4; + } else if (bank->base >= 0x00806000U && bank->base < 0x00827000U) { + priv->page_size = dev->row_size; priv->num_pages = 132; + } else if (bank->base >= dev->flash_base && bank->base < (dev->flash_base + dev->flash_size)) { + priv->page_size = dev->row_size; priv->num_pages = dev->flash_size / dev->row_size; + } else if (bank->base == 0xE000ED10U) { + priv->page_size = dev->row_size; priv->num_pages = 1; + } + } else if (strcmp(dev->name, "PIC32WM") == 0) { /* PIC32WM_BZ6204 mapping similar to pic32wm.c */ + if (base < 0x00010000U) { + priv->page_size = dev->row_size; priv->num_pages = 64; + } else if (bank->base >= 0x00800000U && bank->base < 0x00810000U) { + priv->page_size = dev->row_size; priv->num_pages = 64; + } else if (bank->base >= 0x00810000U && bank->base < 0x00811000U) { + priv->page_size = dev->row_size; priv->num_pages = 4; + } else if (bank->base >= 0x00811000U && bank->base < 0x00812000U) { + priv->page_size = dev->row_size; priv->num_pages = 4; + } else if (bank->base >= dev->flash_base && bank->base < (dev->flash_base + dev->flash_size)) { + priv->page_size = dev->row_size; priv->num_pages = dev->flash_size / dev->row_size; + } else if (bank->base == 0xE000ED10U) { + priv->page_size = dev->row_size; priv->num_pages = 1; + } + } + + /* if not set above, fall back to a single page of row_size */ + if (priv->page_size == 0) { + priv->page_size = dev->row_size; + priv->num_pages = (dev->flash_size / dev->row_size); + } + + bank->size = priv->page_size * priv->num_pages; + bank->num_sectors = priv->num_pages; + + if (bank->sectors) { + free(bank->sectors); + bank->sectors = NULL; + } + + bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector)); + if (!bank->sectors) return ERROR_FAIL; + + for (unsigned int i = 0; i < bank->num_sectors; ++i) { + bank->sectors[i].offset = i * priv->page_size; + bank->sectors[i].size = priv->page_size; + bank->sectors[i].is_protected = 0; + } + + priv->probed = true; + LOG_INFO("%s: probe complete. base=0x%08" PRIx64 " size=0x%08" PRIx32 " pages=%" PRIu32, + dev->name, (uint64_t)bank->base, bank->size, priv->num_pages); + + return ERROR_OK; +} + +/* Erase: page erase (acts on sectors) */ +static int pic32cx_erase(struct flash_bank *bank, unsigned int first, unsigned int last) +{ + struct pic32cx_priv *p = bank->driver_priv; + if (!p) return ERROR_FAIL; + + struct target *t = bank->target; + if (t->state != TARGET_HALTED) return ERROR_TARGET_NOT_HALTED; + + const struct pic32cx_dev *dev = p->dev; + + for (unsigned int i = first; i <= last; ++i) { + uint32_t addr = bank->base + i * p->page_size; + int res = pic32cx_issue_nvmcmd(dev, t, addr, NVMCON_OP_PAGE_ERASE, 0); + if (res != ERROR_OK) return res; + } + return ERROR_OK; +} + +/* Write: row-by-row write (same pattern as originals) */ +static int pic32cx_write(struct flash_bank *bank, const uint8_t *buf, uint32_t offset, uint32_t count) +{ + struct pic32cx_priv *p = bank->driver_priv; + if (!p) return ERROR_FAIL; + + struct target *target = bank->target; + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + const struct pic32cx_dev *dev = p->dev; + uint32_t row_size = dev->row_size; + uint32_t addr = bank->base + offset; + const uint32_t end = addr + count; + + for (uint32_t row_addr = addr & ~(row_size - 1U); row_addr < end; row_addr += row_size) { + uint8_t *row_buf = malloc(row_size); + if (!row_buf) { + LOG_ERROR("Out of memory allocating row buffer"); + return ERROR_FAIL; + } + + int res = target_read_memory(target, row_addr, 4, row_size / 4, row_buf); + if (res != ERROR_OK) { + LOG_ERROR("Failed to read flash row at 0x%08" PRIx32, row_addr); + free(row_buf); + return res; + } + + for (uint32_t i = 0; i < row_size; ++i) { + uint32_t abs_addr = row_addr + i; + if (abs_addr >= addr && abs_addr < end) row_buf[i] = buf[abs_addr - addr]; + } + + res = target_write_buffer(target, RAM_BUF_ADDR, row_size, row_buf); + if (res != ERROR_OK) { + LOG_ERROR("Failed to write row buffer to RAM at 0x%08" PRIx32, (uint32_t)RAM_BUF_ADDR); + free(row_buf); + return res; + } + + res = pic32cx_issue_nvmcmd(dev, target, row_addr, NVMCON_OP_ROW_PROG, RAM_BUF_ADDR); + if (res != ERROR_OK) { + LOG_ERROR("Failed to program row at 0x%08" PRIx32, row_addr); + free(row_buf); + return res; + } + + alive_sleep(2); + free(row_buf); + } + + LOG_INFO("%s: Write completed", p->dev->name); + return ERROR_OK; +} + +/* dsu_reset_deassert - tries to find a bank name (keeps compatibility) */ +COMMAND_HANDLER(pic32cx_handle_dsu_reset_deassert) +{ + struct target *target = get_current_target(CMD_CTX); + if (!target) + return ERROR_FAIL; + + struct flash_bank *bank = get_flash_bank_by_num_noprobe(0); + if (!bank) + return ERROR_FAIL; + + target_write_u8(target, 0x44000001U, 0x02U); + target_write_u32(target, 0x44000100U, 0x8000U); + target_write_u32(target, 0xE000ED0CU, 0x05FA0004U); + target_write_u32(target, 0xE000ED0CU, 0x05FA0000U); + alive_sleep(100); + return ERROR_OK; +} + +/* flash bank attach handler */ +FLASH_BANK_COMMAND_HANDLER(pic32cx_flash_bank_command) +{ + struct pic32cx_priv *chip = calloc(1, sizeof(*chip)); + if (!chip) return ERROR_FAIL; + chip->target = bank->target; + chip->probed = false; + chip->dev = &device_table[0]; /* default */ + chip->page_size = device_table[0].page_size; + bank->driver_priv = chip; + return ERROR_OK; +} + +/* erase_page and write_word wrappers that operate using first table device (manual exec) */ +COMMAND_HANDLER(pic32cx_handle_erase_page_command) +{ + struct target *target = get_current_target(CMD_CTX); + if (!target || CMD_ARGC != 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + uint32_t addr; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr); + + struct flash_bank *bank = get_flash_bank_by_num_noprobe(0); + if (!bank) + return ERROR_FAIL; + + struct pic32cx_priv *p = bank->driver_priv; + const struct pic32cx_dev *dev = (p && p->dev) ? p->dev : &device_table[0]; + + return pic32cx_issue_nvmcmd(dev, target, addr, NVMCON_OP_PAGE_ERASE, 0); +} + +COMMAND_HANDLER(pic32cx_handle_write_word_command) +{ + struct target *target = get_current_target(CMD_CTX); + if (!target || CMD_ARGC != 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + uint32_t addr, value; + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], addr); + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); + + struct flash_bank *bank = get_flash_bank_by_num_noprobe(0); + if (!bank) + return ERROR_FAIL; + + struct pic32cx_priv *p = bank->driver_priv; + const struct pic32cx_dev *dev = (p && p->dev) ? p->dev : &device_table[0]; + + target_write_u32(target, dev->nvmdata, value); + return pic32cx_issue_nvmcmd(dev, target, addr, NVMCON_OP_WORD_PROG, 0); +} + +/* command array registration */ +static const struct command_registration pic32cx_exec_command_handlers[] = { + { + .name = "erase_page", + .handler = pic32cx_handle_erase_page_command, + .mode = COMMAND_EXEC, + .usage = "<address>", + .help = "Erase a flash page at the given address", + }, + { + .name = "write_word", + .handler = pic32cx_handle_write_word_command, + .mode = COMMAND_EXEC, + .usage = "<address> <32bit_hex_value>", + .help = "Write a 32-bit word to flash at the given address", + }, + { + .name = "dsu_reset_deassert", + .handler = pic32cx_handle_dsu_reset_deassert, + .mode = COMMAND_EXEC, + .usage = "", + .help = "Device-specific DSU reset deassert sequence", + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration pic32cx_command_handlers[] = { + { + .name = "pic32cx_bz", + .mode = COMMAND_ANY, + .help = "pic32cx_bz flash command group", + .usage = "", + .chain = pic32cx_exec_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + +const struct flash_driver pic32cx_bz_flash = { + .name = "pic32cx_bz", + .commands = pic32cx_command_handlers, + .flash_bank_command = pic32cx_flash_bank_command, + .erase = pic32cx_erase, + .protect = NULL, + .write = pic32cx_write, + .read = default_flash_read, + .probe = pic32cx_probe, + .auto_probe = pic32cx_probe, + .erase_check = default_flash_blank_check, + .protect_check = NULL, + .free_driver_priv = default_flash_free_driver_priv, +}; diff --git a/src/target/image.h b/src/target/image.h index 03bc068d62..ac42870be7 100644 --- a/src/target/image.h +++ b/src/target/image.h @@ -25,7 +25,7 @@ #endif #define IMAGE_MAX_ERROR_STRING (256) -#define IMAGE_MAX_SECTIONS (512) +#define IMAGE_MAX_SECTIONS (2048) #define IMAGE_MEMORY_CACHE_SIZE (2048) diff --git a/tcl/board/microchip/pic32wm_bz6204_curiosity.cfg b/tcl/board/microchip/pic32wm_bz6204_curiosity.cfg new file mode 100644 index 0000000000..25081e3ea6 --- /dev/null +++ b/tcl/board/microchip/pic32wm_bz6204_curiosity.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Microchip pic32wm_bz6204_curiosity. +# https://www.microchip.com/en-us/development-tool/ea81w68a +# + +source [find interface/cmsis-dap.cfg] + +set CHIPNAME pic32wm + +source [find target/pic32wm.cfg] + +reset_config srst_only diff --git a/tcl/board/microchip/wbz351_curiosity.cfg b/tcl/board/microchip/wbz351_curiosity.cfg new file mode 100644 index 0000000000..54606ea5e2 --- /dev/null +++ b/tcl/board/microchip/wbz351_curiosity.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Microchip WBZ351 Xplained Pro evaluation kit. +# https://www.microchip.com/en-us/development-tool/ev19j06a +# + +source [find interface/cmsis-dap.cfg] + +set CHIPNAME wbz351 + +source [find target/wbz351.cfg] + +reset_config srst_only diff --git a/tcl/board/microchip/wbz450_curiosity.cfg b/tcl/board/microchip/wbz450_curiosity.cfg new file mode 100644 index 0000000000..a92f930c9e --- /dev/null +++ b/tcl/board/microchip/wbz450_curiosity.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Microchip (former Atmel) WBZ451 Xplained Pro evaluation kit. +# https://www.microchip.com/en-us/development-tool/ev22l65a +# + +source [find interface/cmsis-dap.cfg] + +set CHIPNAME wbz450 + +source [find target/wbz450.cfg] + +reset_config srst_only diff --git a/tcl/board/microchip/wbz451_curiosity.cfg b/tcl/board/microchip/wbz451_curiosity.cfg new file mode 100644 index 0000000000..abf2f09f2f --- /dev/null +++ b/tcl/board/microchip/wbz451_curiosity.cfg @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# +# Microchip (former Atmel) WBZ451 Xplained Pro evaluation kit. +# https://www.microchip.com/en-us/development-tool/ev96b94a +# + +source [find interface/cmsis-dap.cfg] + +set CHIPNAME wbz451 + +source [find target/wbz451.cfg] + +reset_config srst_only diff --git a/tcl/target/pic32wm.cfg b/tcl/target/pic32wm.cfg new file mode 100644 index 0000000000..86ef611c1d --- /dev/null +++ b/tcl/target/pic32wm.cfg @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# OpenOCD Target Config for Microchip PIC32WM_BZ6 +# Author: Dinesh Arasu (din...@mi...) + +# --- Setup DAP and CPU --- +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME pic32wm +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + set _DAP_TAPID 0x04D8810B +} + +transport select swd + +swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +# --- Work Area in RAM --- +$_TARGETNAME configure -work-area-phys 0x20000000 \ + -work-area-size 0x80000 \ + -work-area-backup 0 + +# --- Reset Behavior --- +$_TARGETNAME configure -event reset-deassert-post { + pic32cx_bz dsu_reset_deassert +} + +reset_config srst_only srst_nogate + +adapter speed 2000 + +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +# --- Flash Banks --- +flash bank pic32wm_flash pic32cx_bz 0x01000000 0x00200000 0 0 $_TARGETNAME + +flash bank pic32wm_Secure_boot pic32cx_bz 0x00000000 0x10000 0 0 $_TARGETNAME + +flash bank pic32wm_boot pic32cx_bz 0x00800000 0x10000 0 0 $_TARGETNAME + +flash bank pic32wm_device_config pic32cx_bz 0x00810000 0x1000 0 0 $_TARGETNAME + +flash bank pic32wm_otp_config pic32cx_bz 0x00811000 0x1000 0 0 $_TARGETNAME + +flash bank pic32wm_config_CM4F pic32cx_bz 0xE000ed10 0x100 0 0 $_TARGETNAME \ No newline at end of file diff --git a/tcl/target/wbz351.cfg b/tcl/target/wbz351.cfg new file mode 100644 index 0000000000..25965c629b --- /dev/null +++ b/tcl/target/wbz351.cfg @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# OpenOCD Target Config for Microchip WBZ351 +# Author: Dinesh Arasu (din...@mi...) + +# --- Setup DAP and CPU --- +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME wbz351 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + set _DAP_TAPID 0x04D8810B +} + +transport select swd + +swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +# --- Work Area in RAM --- +$_TARGETNAME configure -work-area-phys 0x20000000 \ + -work-area-size 0x18000 \ + -work-area-backup 0 + +# --- Reset Behavior --- +$_TARGETNAME configure -event reset-deassert-post { + pic32cx_bz dsu_reset_deassert +} + +reset_config srst_only srst_nogate + +adapter speed 2000 + +if {![using_hla]} { + # if srst is not fitted use SYSRESETREQ to + # perform a soft reset + cortex_m reset_config sysresetreq +} + +# --- Flash Banks --- +flash bank wbz351_flash pic32cx_bz 0x01000000 0x00080000 0 0 $_TARGETNAME + +flash bank wbz351_Secure_boot pic32cx_bz 0x00000000 0x10000 0 0 $_TARGETNAME + +flash bank wbz351_boot pic32cx_bz 0x00800000 0x5000 0 0 $_TARGETNAME + +flash bank wbz351_device_config pic32cx_bz 0x00805000 0x1000 0 0 $_TARGETNAME + +flash bank wbz351_otp_config pic32cx_bz 0x00806000 0x21000 0 0 $_TARGETNAME + +flash bank wbz351_config_CM4F pic32cx_bz 0xE000ed10 0x100 0 0 $_TARGETNAME + diff --git a/tcl/target/wbz450.cfg b/tcl/target/wbz450.cfg new file mode 100644 index 0000000000..efcc16f8a7 --- /dev/null +++ b/tcl/target/wbz450.cfg @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# OpenOCD Target Config for Microchip WBZ450 +# Author: Dinesh Arasu (din...@mi...) + +# --- Setup DAP and CPU --- +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME wbz450 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + set _DAP_TAPID 0x04D8810B +} + +transport select swd + +swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +# --- Work Area in RAM --- +$_TARGETNAME configure -work-area-phys 0x20000000 \ + -work-area-size 0x20000 \ + -work-area-backup 0 + +# --- Reset Behavior --- +$_TARGETNAME configure -event reset-deassert-post { + pic32cx_bz dsu_reset_deassert +} + +reset_config srst_only srst_nogate + +adapter speed 2000 + +if {![using_hla]} { + cortex_m reset_config sysresetreq +} + +# --- Flash Banks --- +flash bank wbz450_flash pic32cx_bz 0x01000000 0x00100000 0 0 $_TARGETNAME + +flash bank wbz450_boot pic32cx_bz 0x00000000 0x5000 0 0 $_TARGETNAME + +flash bank wbz450_device_config pic32cx_bz 0x00005000 0x1000 0 0 $_TARGETNAME + +flash bank wbz450_otp pic32cx_bz 0x00006000 0x1000 0 0 $_TARGETNAME + +flash bank wbz450_configbits pic32cx_bz 0x00045000 0x2000 0 0 $_TARGETNAME + +flash bank wbz450_config_CM4F pic32cx_bz 0xE000ed10 0x100 0 0 $_TARGETNAME \ No newline at end of file diff --git a/tcl/target/wbz451.cfg b/tcl/target/wbz451.cfg new file mode 100644 index 0000000000..53e6bb5c5e --- /dev/null +++ b/tcl/target/wbz451.cfg @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# OpenOCD Target Config for Microchip WBZ451 +# Author: Dinesh Arasu (din...@mi...) + +# --- Setup DAP and CPU --- +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME wbz451 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + set _DAP_TAPID 0x04D8810B +} + +transport select swd + +swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID +dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap + +# --- Work Area in RAM --- +$_TARGETNAME configure -work-area-phys 0x20000000 \ + -work-area-size 0x20000 \ + -work-area-backup 0 + +# --- Reset Behavior --- +$_TARGETNAME configure -event reset-deassert-post { + pic32cx_bz dsu_reset_deassert +} + +reset_config srst_only srst_nogate + +adapter speed 2000 + +if {![using_hla]} { + cortex_m reset_config sysresetreq +} + +# --- Flash Banks --- +flash bank wbz451_flash pic32cx_bz 0x01000000 0x00100000 0 0 $_TARGETNAME + +flash bank wbz451_boot pic32cx_bz 0x00000000 0x5000 0 0 $_TARGETNAME + +flash bank wbz451_device_config pic32cx_bz 0x00005000 0x1000 0 0 $_TARGETNAME + +flash bank wbz451_otp pic32cx_bz 0x00006000 0x1000 0 0 $_TARGETNAME + +flash bank wbz451_configbits pic32cx_bz 0x00045000 0x2000 0 0 $_TARGETNAME + +flash bank wbz451_config_CM4F pic32cx_bz 0xE000ed10 0x100 0 0 $_TARGETNAME \ No newline at end of file -- |
From: <ge...@op...> - 2025-10-12 10:26:50
|
This is an automated email from Gerrit. "Antonio Borneo <bor...@gm...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9167 -- gerrit commit 2e10729ccc3388832454d52997e7af4eeb8c8923 Author: Antonio Borneo <bor...@gm...> Date: Sun Oct 12 12:10:46 2025 +0200 target: cortex-m: fix support for armv8m caches Scan-build is unable to correctly follow the deferred loading of queued read, finalized by the atomic write, thus it incorrectly claims that the arrays d_u_ccsidr[] and i_ccsidr[] could be carry not initialized values: armv7m_cache.c:154:31: warning: 1st function call argument is an uninitialized value [core.CallAndMessage] cache->arch[cl].d_u_size = decode_ccsidr(d_u_ccsidr[cl]); armv7m_cache.c:172:29: warning: 1st function call argument is an uninitialized value [core.CallAndMessage] cache->arch[cl].i_size = decode_ccsidr(i_ccsidr[cl]); Initialize the arrays to zero to hide this false positive. Change-Id: I6d1e88093cb8807848643139647a571c1b566aa8 Signed-off-by: Antonio Borneo <bor...@gm...> Fixes: 04da6e2c6246 ("target: cortex-m: add support for armv8m caches") diff --git a/src/target/armv7m_cache.c b/src/target/armv7m_cache.c index cb57c0e25b..cc0c9d1404 100644 --- a/src/target/armv7m_cache.c +++ b/src/target/armv7m_cache.c @@ -111,7 +111,7 @@ int armv7m_identify_cache(struct target *target) clidr, cache->loc); // retrieve all available inner caches - uint32_t d_u_ccsidr[8], i_ccsidr[8]; + uint32_t d_u_ccsidr[8] = {0}, i_ccsidr[8] = {0}; for (unsigned int cl = 0; cl < cache->loc; cl++) { unsigned int ctype = FIELD_GET(CLIDR_CTYPE_MASK(cl + 1), clidr); -- |
From: <ge...@op...> - 2025-10-12 09:51:45
|
This is an automated email from Gerrit. "Antonio Borneo <bor...@gm...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9166 -- gerrit commit eb495be6e8ab72dacd477d2853d87fa326681ffa Author: Antonio Borneo <bor...@gm...> Date: Sun Oct 12 11:30:00 2025 +0200 helper/log: mark 'fmt' argument of alloc_*printf() as not NULL Even after commit e12ceddd5ee4 ("helper/log: mark `fmt` argument of `alloc_vprintf()` as format string"), the GCC compiler still reports that alloc_vprintf() could call vsnprintf() with a NULL format parameter. Inform the compiler that alloc_vprintf() cannot accept NULL as format string. Add an assert() in alloc_vprintf() so even compilers that do not use the function attribute 'nonnull' will play safe. While there, extend the same fixes to alloc_printf() too. Change-Id: Idfa4fe9c6dfb2acfbf434c392237937ae03f0e8a Signed-off-by: Antonio Borneo <bor...@gm...> Reported-by: Parshintsev Anatoly <ana...@sy...> diff --git a/src/helper/log.c b/src/helper/log.c index d8c4e09ac7..53463b526c 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -354,6 +354,8 @@ char *alloc_vprintf(const char *fmt, va_list ap) int len; char *string; + assert(fmt); + /* determine the length of the buffer needed */ va_copy(ap_copy, ap); len = vsnprintf(NULL, 0, fmt, ap_copy); diff --git a/src/helper/log.h b/src/helper/log.h index ac24f8e833..06770553c4 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -15,6 +15,7 @@ #define OPENOCD_HELPER_LOG_H #include <helper/command.h> +#include <helper/compiler.h> /* To achieve C99 printf compatibility in MinGW, gnu_printf should be * used for __attribute__((format( ... ))), with GCC v4.4 or later @@ -86,9 +87,9 @@ int log_add_callback(log_callback_fn fn, void *priv); int log_remove_callback(log_callback_fn fn, void *priv); char *alloc_vprintf(const char *fmt, va_list ap) - __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 0))); + __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 0))) __nonnull((1)); char *alloc_printf(const char *fmt, ...) - __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 2))); + __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 2))) __nonnull((1)); const char *find_nonprint_char(const char *buf, unsigned int buf_len); -- |