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
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <ge...@op...> - 2025-05-25 04:06:52
|
This is an automated email from Gerrit. "Brandon Martin <mar...@mo...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8933 -- gerrit commit bdd42ee831329890e3ec2fe60742e992993b2a6c Author: Brandon Martin <mar...@mo...> Date: Mon May 19 06:30:26 2025 -0400 On-chip algorithm programming for FLEXSPI This considerably improves programming throughput on the order of 4-5x. There are currently several IMXRT1020'isms in the algorithm code with respect to disabling various watchdogs. These will need to be factored out. Change-Id: Ibf61dcaad09d9d3dcea1cbfe4e825c67935cdb93 Signed-off-by: Brandon Martin <mar...@mo...> diff --git a/contrib/loaders/flash/fsl_flexspi_blockwrite.S b/contrib/loaders/flash/fsl_flexspi_blockwrite.S new file mode 100644 index 0000000000..9619c65b69 --- /dev/null +++ b/contrib/loaders/flash/fsl_flexspi_blockwrite.S @@ -0,0 +1,179 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Copyright (C) 2025 by Brandon Martin (Mothic Technologies LLC) * + * mar...@mo... * + ***************************************************************************/ + + .text + .syntax unified + .cpu cortex-m7 + .thumb + .thumb_func + + /* + * Params: + * r0 = flash destination address [in/out] + * r1 = blkcount - 0 indicates success [in/out] + * r2 = blksize in 32-bit words (must be <= IP TX FIFO length) + * r3 = workarea (streaming FIFO) start address + * r4 = workarea (streaming FIFO) end address + * r5 = FLEXSPI register base + */ + +#include "../../../src/flash/nor/fsl_flexspi.h" + + .macro wait_ipcmd +0: + ldr r7, [r5, #REG_INTR] + ands r6, r7, #INTR_IPCMDERR + bne error + ands r6, r7, #INTR_IPCMDDONE + beq 0b + .endm + + .macro clear_intr + mov r6, #(INTR_AHBCMDERR | INTR_IPCMDERR | INTR_AHBCMDGE | INTR_IPCMDGE | INTR_IPCMDDONE | INTR_IPRXWA | \ + INTR_IPTXWE) + str r6, [r5, #REG_INTR] + .endm + + .align 4 + +start: + cpsid i + mov r6, #0 + ldr r7, wdog1 + strh r6, [r7, #8] + mov r6, #0x0030 + strh r6, [r7, #0] + ldr r7, wdog2 + mov r6, #0 + strh r6, [r7, #8] + mov r6, #0x0030 + strh r6, [r7, #0] + ldr r7, rtwdog + ldr r6, [r7] + ands r6, #BIT(7) + beq rtwdog_disabled + ldr r6, rtwdog_unlock + str r6, [r7, #4] + mov r6, #0x00002120 + str r6, [r7] +rtwdog_disabled: + ldr r7, src + ldr r6, src_scr_disable_wdogs + str r6, [r7] + mov r6, #0x1ff + str r6, [r7, #8] + ldr r7, systick + mov r6, #0 + str r6, [r7] + +next_block: + /* Write enable */ + clear_intr + str r0, [r5, #REG_IPCR0] /* flash address */ + mov r6, #(IPCR1_IDATASZ(0) | IPCR1_ISEQID(LUTNUM_WRITE_ENABLE) | IPCR1_ISEQNUM(0)) + str r6, [r5, #REG_IPCR1] /* data length and LUT program info */ + mov r6, #IPCMD_TRG + str r6, [r5, #REG_IPCMD] /* initiate command */ + wait_ipcmd + + /* Configure the TX FIFO for a block */ + lsr r6, r2, #1 + sub r6, r6, #1 + lsl r6, r6, #2 + orr r6, r6, #1 + str r6, [r5, #REG_IPTXFCR] + + /* Load TX FIFO with this block's data */ + mov r8, #0 /* block word count [r8] */ + add r5, r5, #REG_TFDR + ldr r6, [r3, #4] /* read rp [r6] */ +wait_fifo: + ldr r7, [r3, #0] /* read wp [r7] */ + cmp r7, #0 /* abort if wp == 0 */ + beq exit + + cmp r6, r7 /* wait until rp != wp */ + beq wait_fifo + + ldr r7, [r6] /* read from rp */ + str r7, [r5, r8, lsl #2] /* store to IP TX FIFO */ + + add r6, #4 /* rp += 4 */ + cmp r6, r4 /* Wrap? */ + bcc no_wrap + mov r6, r3 + add r6, r6, #8 +no_wrap: + add r8, r8, #1 + cmp r2, r8 /* need more data for block? */ + bne wait_fifo + + /* Entire block written to TX FIFO */ + str r6, [r3, #4] /* Store rp */ + sub r5, r5, #REG_TFDR + + /* Send write command + data */ + clear_intr + str r0, [r5, #REG_IPCR0] /* flash address */ + mov r6, #(IPCR1_ISEQID(LUTNUM_DRV) | IPCR1_ISEQNUM(0)) + orr r6, r6, r2, lsl #2 + str r6, [r5, #REG_IPCR1] /* data length and LUT program info */ + mov r6, #IPCMD_TRG + str r6, [r5, #REG_IPCMD] /* initiate command */ + wait_ipcmd + + /* Read status and wait for completion */ +check_busy: + clear_intr + mov r6, #IPRXFCR_RXWMRK(1) | IPRXFCR_CLRIPRXF + str r6, [r5, #REG_IPRXFCR] + mov r6, #0 + str r6, [r5, #REG_IPCR0] + ldr r6, wait_busy_ipcr1 + str r6, [r5, #REG_IPCR1] + mov r6, #IPCMD_TRG + str r6, [r5, #REG_IPCMD] /* initiate command */ + +wait_status: + wait_ipcmd + + ldr r7, [r5, #REG_RFDR] + ands r6, r7, #SPIFLASH_BSY_BIT + bne check_busy + ands r6, r7, #SPIFLASH_WE_BIT + bne error + + /* Block is complete */ + add r0, r0, r2, lsl #2 /* flash address += blksize - increment after error check since it's output */ + + subs r1, #1 /* blkcount-- */ + bne next_block + b exit + +error: + mov r5, #0 + str r5, [r3, #4] /* set rp = 0 on error */ + +exit: + bkpt #0 + +wait_busy_ipcr1: + .word (IPCR1_IDATASZ(4) | IPCR1_ISEQID(LUTNUM_READ_STATUS) | IPCR1_ISEQNUM(0)) +wdog1: + .word 0x400b8000 +wdog2: + .word 0x400d0000 +rtwdog: + .word 0x400bc000 +rtwdog_unlock: + .word 0xd928c520 +systick: + .word 0xe000e010 +src: + .word 0x400f8000 +src_scr_disable_wdogs: + .word 0x504802a0 diff --git a/contrib/loaders/flash/fsl_flexspi_blockwrite.inc b/contrib/loaders/flash/fsl_flexspi_blockwrite.inc new file mode 100644 index 0000000000..31f88a8205 --- /dev/null +++ b/contrib/loaders/flash/fsl_flexspi_blockwrite.inc @@ -0,0 +1,23 @@ +/* Autogenerated with ../../../src/helper/bin2char.sh */ +0x72,0xb6,0x4f,0xf0,0x00,0x06,0xdf,0xf8,0x38,0x71,0x3e,0x81,0x4f,0xf0,0x30,0x06, +0x3e,0x80,0xdf,0xf8,0x30,0x71,0x4f,0xf0,0x00,0x06,0x3e,0x81,0x4f,0xf0,0x30,0x06, +0x3e,0x80,0x49,0x4f,0x3e,0x68,0x16,0xf0,0x80,0x06,0x04,0xd0,0x47,0x4e,0x7e,0x60, +0x42,0xf2,0x20,0x16,0x3e,0x60,0x47,0x4f,0x47,0x4e,0x3e,0x60,0x40,0xf2,0xff,0x16, +0xbe,0x60,0x43,0x4f,0x4f,0xf0,0x00,0x06,0x3e,0x60,0x4f,0xf0,0x7f,0x06,0x6e,0x61, +0xc5,0xf8,0xa0,0x00,0x4f,0xf4,0x40,0x36,0xc5,0xf8,0xa4,0x60,0x4f,0xf0,0x01,0x06, +0xc5,0xf8,0xb0,0x60,0x6f,0x69,0x17,0xf0,0x08,0x06,0x63,0xd1,0x17,0xf0,0x01,0x06, +0xf8,0xd0,0x4f,0xea,0x52,0x06,0xa6,0xf1,0x01,0x06,0x4f,0xea,0x86,0x06,0x46,0xf0, +0x01,0x06,0xc5,0xf8,0xbc,0x60,0x4f,0xf0,0x00,0x08,0x05,0xf5,0xc0,0x75,0x5e,0x68, +0x1f,0x68,0x00,0x2f,0x51,0xd0,0xbe,0x42,0xfa,0xd0,0x37,0x68,0x45,0xf8,0x28,0x70, +0x06,0xf1,0x04,0x06,0xa6,0x42,0x02,0xd3,0x1e,0x46,0x06,0xf1,0x08,0x06,0x08,0xf1, +0x01,0x08,0x42,0x45,0xec,0xd1,0x5e,0x60,0xa5,0xf5,0xc0,0x75,0x4f,0xf0,0x7f,0x06, +0x6e,0x61,0xc5,0xf8,0xa0,0x00,0x4f,0xf4,0x20,0x26,0x46,0xea,0x82,0x06,0xc5,0xf8, +0xa4,0x60,0x4f,0xf0,0x01,0x06,0xc5,0xf8,0xb0,0x60,0x6f,0x69,0x17,0xf0,0x08,0x06, +0x28,0xd1,0x17,0xf0,0x01,0x06,0xf8,0xd0,0x4f,0xf0,0x7f,0x06,0x6e,0x61,0x4f,0xf0, +0x05,0x06,0xc5,0xf8,0xb8,0x60,0x4f,0xf0,0x00,0x06,0xc5,0xf8,0xa0,0x60,0x0f,0x4e, +0xc5,0xf8,0xa4,0x60,0x4f,0xf0,0x01,0x06,0xc5,0xf8,0xb0,0x60,0x6f,0x69,0x17,0xf0, +0x08,0x06,0x0f,0xd1,0x17,0xf0,0x01,0x06,0xf8,0xd0,0xd5,0xf8,0x00,0x71,0x17,0xf0, +0x01,0x06,0xe1,0xd1,0x17,0xf0,0x02,0x06,0x04,0xd1,0x00,0xeb,0x82,0x00,0x01,0x39, +0x8b,0xd1,0x02,0xe0,0x4f,0xf0,0x00,0x05,0x5d,0x60,0x00,0xbe,0x04,0x00,0x01,0x00, +0x00,0x80,0x0b,0x40,0x00,0x00,0x0d,0x40,0x00,0xc0,0x0b,0x40,0x20,0xc5,0x28,0xd9, +0x10,0xe0,0x00,0xe0,0x00,0x80,0x0f,0x40,0xa0,0x02,0x48,0x50, diff --git a/src/flash/nor/fsl_flexspi.c b/src/flash/nor/fsl_flexspi.c index 06c7ed9aa3..3ee997d505 100644 --- a/src/flash/nor/fsl_flexspi.c +++ b/src/flash/nor/fsl_flexspi.c @@ -44,11 +44,15 @@ #endif #include "imp.h" -#include "spi.h" #include <helper/align.h> +#include <helper/binarybuffer.h> #include <helper/bits.h> #include <helper/time_support.h> +#include <target/algorithm.h> +#include <target/armv7m.h> + +#include "fsl_flexspi.h" #define TIMEOUT_EXEC_IPCMD 100 #define TIMEOUT_RESET 100 @@ -56,166 +60,6 @@ #define TIMEOUT_FLASH_ERASE_CHIP 90000 #define TIMEOUT_FLASH_PROGRAM 250 -/* These are the base addresses used on the IMXRT1020 */ -#define FLEXSPI_DEFAULT_IOBASE 0x402A8000 -#define FLEXSPI_LINEAR_AHBASE 0x60000000 -#define FLEXSPI_TX_FIFO_AHBASE 0x7F800000 -#define FLEXSPI_RX_FIFO_AHBASE 0x7FC00000 - -/* The documentation implies that these may be chip-specific tweakables */ -#define FLEXSPI_AHB_TX_BUFSZ 64 -#define FLEXSPI_AHB_RX_BUFSZ 1024 -#define FLEXSPI_IP_TX_FIFOSZ 128 -#define FLEXSPI_IP_RX_FIFOSZ 128 - -/* On-chip registers and fields */ -#define REG_MCR0 0x00 -#define MCR0_SWRESET BIT(0) -#define MCR0_MDIS BIT(1) -#define MCR0_ARDFEN BIT(6) -#define MCR0_ATDFEN BIT(7) - -#define REG_AHBCR 0x0C -#define AHBCR_ALIGNMENT(x) (((x) & 0x03) << 20) -#define AHBCR_READSZALIGN BIT(10) -#define AHBCR_READADDROPT BIT(6) -#define AHBCR_PREFETCHEN BIT(5) -#define AHBCR_BUFFERABLEEN BIT(4) -#define AHBCR_CACHABLEEN BIT(3) -#define AHBCR_APAREN BIT(0) - -#define REG_INTR 0x14 -#define INTR_IPCMDDONE BIT(0) -#define INTR_IPCMDGE BIT(1) -#define INTR_AHBCMDGE BIT(2) -#define INTR_IPCMDERR BIT(3) -#define INTR_AHBCMDERR BIT(4) -#define INTR_IPRXWA BIT(5) -#define INTR_IPTXWE BIT(6) -#define INTR_SCKSTOPBYRD BIT(8) -#define INTR_SCKSTOPBYWR BIT(9) -#define INTR_AHBBUSTTIMEOUT BIT(10) -#define INTR_SEQTIMEOUT BIT(11) -#define INTR_IPCMDSECUREVIO BIT(16) - -#define REG_LUTKEY 0x18 -#define LUTKEY_MAGIC 0x5AF05AF0 - -#define REG_LUTCR 0x1C -#define LUTCR_LOCK BIT(0) -#define LUTCR_UNLOCK BIT(1) -#define LUTCR_PROTECT BIT(2) - -#define REG_AHBRXBUF0CR0 0x20 -#define REG_AHBRXBUF1CR0 0x24 -#define REG_AHBRXBUF2CR0 0x28 -#define REG_AHBRXBUF3CR0 0x2C -#define AHBRXBUFNCR0_BUFSZ(x) (((x) & 0xFF) << 0) -#define AHBRXBUFNCR0_MSTRID(x) (((x) & 0x0F) << 16) -#define AHBRXBUFNCR0_PRIORITY(x) (((x) & 0x03) << 24) -#define AHBRXBUFNCR0_REGIONEN BIT(30) -#define AHBRXBUFNCR0_PREFETCHEN BIT(31) - -#define REG_FLSHA1CR0 0x60 -#define FLSHNNCR0_FLASHSZ(x) (((x) & 0x7FFFFF) << 0) - -#define REG_FLSHA1CR1 0x70 -#define FLSHNNCR1_TCSS(x) (((x) & 0x1F) << 0) -#define FLSHNNCR1_TCSH(x) (((x) & 0x1F) << 5) -#define FLSHNNCR1_WA BIT(10) -#define FLSHNNCR1_CAS(x) (((x) & 0x0F) << 11) -#define FLSHNNCR1_CSINTERVALUNIT BIT(15) -#define FLSHNNCR1_CSINTERVAL(x) (((x) & 0xFFFF) << 16) - -#define REG_FLSHA1CR2 0x80 -#define FLSHNNCR2_ARDSEQID(x) (((x) & 0x0F) << 0) -#define FLSHNNCR2_ARDSEQNUM(x) (((x) & 0x07) << 5) -#define FLSHNNCR2_AWRSEQID(x) (((x) & 0x0F) << 8) -#define FLSHNNCR2_AWRSEQNUM(x) (((x) & 0x07) << 13) -#define FLSHNNCR2_AWRWAIT(x) (((x) & 0x0FFF) << 16) -#define FLSHNNCR2_AWRWAITUNIT(x) (((x) & 0x07) << 28) -#define AWRWAITUNIT_2AHB 0 -#define AWRWAITUNIT_8AHB 1 -#define AWRWAITUNIT_32AHB 2 -#define AWRWAITUNIT_128AHB 3 -#define AWRWAITUNIT_512AHB 4 -#define AWRWAITUNIT_2048AHB 5 -#define AWRWAITUNIT_8192AHB 6 -#define AWRWAITUNIT_32768AHB 7 -#define FLSHNNCR2_CLRINSTRPTR BIT(31) - -#define REG_FLSHCR4 0x94 -#define FLSHCR4_WMOPT1 BIT(0) -#define FLSHCR4_WMENA BIT(2) -#define FLSHCR4_WMENB BIT(3) -#define FLSHCR4_PAR_WM(x) (((x) & 0x03) << 9) -#define FLSHCR4_PAR_ADDR_ADJ_DIS BIT(11) - -#define REG_IPCR0 0xA0 -#define IPCR0_SFAR(x) (x) - -#define REG_IPCR1 0xA4 -#define IPCR1_IDATASZ(x) (((x) & 0xFFFF) << 0) -#define IPCR1_ISEQID(x) (((x) & 0x0F) << 16) -#define IPCR1_ISEQNUM(x) (((x) & 0x0F) << 24) -#define IPCR1_IPAREN BIT(31) - -#define REG_IPCMD 0xB0 -#define IPCMD_TRG BIT(0) - -#define REG_IPRXFCR 0xB8 -#define IPRXFCR_CLRIPRXF BIT(0) -#define IPRXFCR_RXDMAEN BIT(1) -#define IPRXFCR_RXWMRK(x) (((x) & 0x0F) << 2) - -#define REG_IPTXFCR 0xBC -#define IPTXFCR_CLRIPTXF BIT(0) -#define IPTXFCR_TXDMAEN BIT(1) -#define IPTXFCR_TXWMRK(x) (((x) & 0x0F) << 2) - -#define REG_STS1 0xE4 - -#define REG_RFDR 0x100 -#define REG_TFDR 0x180 - -#define REG_LUT_BASE 0x200 -#define REG_LUT(x) (REG_LUT_BASE + (x) * 4) - -/* - * This LUT sequence number is used only during probe to read flash IDs - * - * The LUT sequence number 0 is the default for FlexSPI NOR (and NAND?) boot - */ -#define LUTNUM_AHB_READ 0 - -/* - * The (only) LUT sequence number to be used by the driver after probing - * - * Other LUT sequence numbers will not be touched and can be used by - * application code without impeding operating by the driver without controller - * re-initialization if some other basic conditions are met. - * - * The LUT sequence number 10 is not used by boot procedures nor the Freescale - * sample code - */ -#define LUTNUM_DRV 10 - -/* Instruction set for the LUT register (SDR only) */ -#define OPCODE_STOP 0 -#define OPCODE_CMD 1 -#define OPCODE_RADDR 2 -#define OPCODE_CADDR 3 -#define OPCODE_MODE1 4 -#define OPCODE_MODE2 5 -#define OPCODE_MODE4 6 -#define OPCODE_MODE8 7 -#define OPCODE_WRITE 8 -#define OPCODE_READ 9 -#define OPCODE_LEARN 10 -#define OPCODE_DATSZ 11 -#define OPCODE_DUMMY 12 -#define OPCODE_JMP_ON_CS 31 - /* * Macro for constructing the LUT entries with the following * register layout: @@ -289,6 +133,8 @@ static int read_rxfifo(struct flash_bank *bank, uint8_t *buf, uint32_t datalen) uint32_t nbytes; uint8_t bytes[4]; + LOG_DEBUG("want %" PRIx32 "B", datalen); + ret = target_write_u32(target, io_base + REG_IPRXFCR, IPRXFCR_RXWMRK(datalen / 8 - 1)); if (ret != ERROR_OK) goto err; @@ -431,8 +277,8 @@ err: return ret; } -static int execute_ipcmd_read(struct flash_bank *bank, uint8_t opcode, - void *buf, uint32_t datalen) +static int execute_ipcmd_read_with_lutnum(struct flash_bank *bank, uint8_t opcode, + void *buf, uint32_t datalen, uint32_t lutnum) { struct target *target = bank->target; struct fsl_flexspi_flash_bank *flexspi_info = bank->driver_priv; @@ -456,7 +302,7 @@ static int execute_ipcmd_read(struct flash_bank *bank, uint8_t opcode, lutval[lutidx / 2] |= LUT_DEF(lutidx, OPCODE_STOP, 0, 0); lutidx++; - ret = write_lut_memory(bank, lutval, LUTNUM_DRV); + ret = write_lut_memory(bank, lutval, lutnum); if (ret != ERROR_OK) goto err; @@ -481,7 +327,7 @@ static int execute_ipcmd_read(struct flash_bank *bank, uint8_t opcode, ret = target_write_u32(target, io_base + REG_IPCR1, - IPCR1_IDATASZ(datalen) | IPCR1_ISEQID(LUTNUM_DRV) | IPCR1_ISEQNUM(0)); + IPCR1_IDATASZ(datalen) | IPCR1_ISEQID(lutnum) | IPCR1_ISEQNUM(0)); if (ret != ERROR_OK) goto err; @@ -527,6 +373,12 @@ err: return ret; } +static int execute_ipcmd_read(struct flash_bank *bank, uint8_t opcode, + void *buf, uint32_t datalen) +{ + return execute_ipcmd_read_with_lutnum(bank, opcode, buf, datalen, LUTNUM_DRV); +} + static int execute_ipcmd_write(struct flash_bank *bank, uint8_t opcode, const void *buf, uint32_t datalen) { @@ -649,7 +501,7 @@ static int read_status_reg(struct flash_bank *bank, uint8_t *statusreg) *statusreg = 0; - ret = execute_ipcmd_read(bank, SPIFLASH_READ_STATUS, statusreg, sizeof(*statusreg)); + ret = execute_ipcmd_read_with_lutnum(bank, SPIFLASH_READ_STATUS, statusreg, sizeof(*statusreg), LUTNUM_READ_STATUS); if (ret != ERROR_OK) goto err; @@ -665,7 +517,7 @@ static int write_enable(struct flash_bank *bank) LOG_DEBUG("reached"); - ret = execute_ipcmd_read(bank, SPIFLASH_WRITE_ENABLE, NULL, 0); + ret = execute_ipcmd_read_with_lutnum(bank, SPIFLASH_WRITE_ENABLE, NULL, 0, LUTNUM_WRITE_ENABLE); if (ret != ERROR_OK) goto err; @@ -700,22 +552,13 @@ static int poll_flash_status(struct flash_bank *bank, uint8_t value, uint8_t mas return ERROR_TIMEOUT_REACHED; } -static int execute_page_program(struct flash_bank *bank, uint8_t opcode, - const void *buf, uint32_t flashaddr, uint32_t datalen) +static int setup_write_lut(struct flash_bank *bank, uint8_t opcode, + uint32_t writelen) { - struct target *target = bank->target; - struct fsl_flexspi_flash_bank *flexspi_info = bank->driver_priv; - uint32_t io_base = flexspi_info->io_base; + LOG_DEBUG("opcode: %02x, writelen: %u", opcode, writelen); + uint32_t lutval[4] = {}; int lutidx = 0; - uint8_t status; - int ret; - - LOG_DEBUG("%" PRIu32 "B to 0x%08" PRIx32, datalen, flashaddr); - - ret = write_enable(bank); - if (ret != ERROR_OK) - goto err; /* Prepare sequence LUT */ lutval[lutidx / 2] |= LUT_DEF(lutidx, OPCODE_CMD, lut_pad(1), opcode); @@ -732,18 +575,36 @@ static int execute_page_program(struct flash_bank *bank, uint8_t opcode, lutval[lutidx / 2] |= LUT_DEF(lutidx, OPCODE_RADDR, lut_pad(1), naddrbytes * 8); lutidx++; - if (datalen > 0) { - lutval[lutidx / 2] |= LUT_DEF(lutidx, OPCODE_WRITE, lut_pad(1), datalen); + if (writelen > 0) { + lutval[lutidx / 2] |= LUT_DEF(lutidx, OPCODE_WRITE, lut_pad(1), writelen); lutidx++; } lutval[lutidx / 2] |= LUT_DEF(lutidx, OPCODE_STOP, 0, 0); lutidx++; - ret = write_lut_memory(bank, lutval, LUTNUM_DRV); + return write_lut_memory(bank, lutval, LUTNUM_DRV); +} + +static int program_page(struct flash_bank *bank, uint8_t opcode, + const void *buf, uint32_t flashaddr, uint32_t datalen) +{ + struct target *target = bank->target; + struct fsl_flexspi_flash_bank *flexspi_info = bank->driver_priv; + uint32_t io_base = flexspi_info->io_base; + uint8_t status; + int ret; + + LOG_DEBUG("%" PRIu32 "B to 0x%08" PRIx32, datalen, flashaddr); + + ret = write_enable(bank); if (ret != ERROR_OK) goto err; + ret = setup_write_lut(bank, opcode, datalen); + if (ret != ERROR_OK) + return ret; + /* Clear any stray pending status */ ret = target_write_u32(target, io_base + REG_INTR, @@ -810,6 +671,122 @@ err: return ret; } +/* Kinetis Program-LongWord Microcodes */ +static const uint8_t flexspi_flash_blockwrite_algo[] = { +#include "../../../contrib/loaders/flash/fsl_flexspi_blockwrite.inc" +}; + +static int program_block(struct flash_bank *bank, uint8_t opcode, + const void *buf, uint32_t flashaddr, uint32_t datalen, uint32_t blksize) +{ + struct target *target = bank->target; + struct fsl_flexspi_flash_bank *flexspi_info = bank->driver_priv; + uint32_t progdata_size; + struct working_area *algo; + struct working_area *progdata; + struct reg_param reg_params[6]; + struct armv7m_algorithm armv7m_info; + uint32_t end_address; + uint32_t blkcount; + int ret; + uint8_t statusreg; + + /* Set up driver LUT for block write */ + ret = setup_write_lut(bank, opcode, blksize); + if (ret != ERROR_OK) + return ret; + + /* Run an extra read status command to ensure LUTNUM_READ_STATUS is set up */ + ret = read_status_reg(bank, &statusreg); + if (ret != ERROR_OK) + return ret; + + /* Likewise for write enable */ + ret = write_enable(bank); + if (ret != ERROR_OK) + return ret; + + /* allocate working area with flash programming code */ + if (target_alloc_working_area(target, sizeof(flexspi_flash_blockwrite_algo), + &algo) != ERROR_OK) { + LOG_WARNING("no working area available, can't do block memory writes"); + ret = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + goto out_noalgo; + } + + ret = target_write_buffer(target, algo->address, + sizeof(flexspi_flash_blockwrite_algo), flexspi_flash_blockwrite_algo); + if (ret != ERROR_OK) + goto out_noprogdata; + + /* memory buffer, size must be (multiple of blksize) plus 8 */ + progdata_size = target_get_working_area_avail(target) & ~(sizeof(uint32_t) - 1); + if (progdata_size < (blksize * 2 + 8)) { + LOG_WARNING("large enough working area not available for block writes"); + ret = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + goto out_noprogdata; + } + + /* Anything bigger than 32k seems superfluous */ + progdata_size = MIN(progdata_size, 32768 + 8); + + /* Ensure it's a multiple of the blksize plus the extra 8 bytes for the rp/wp */ + progdata_size = ALIGN_DOWN(progdata_size, blksize) + 8; + + if (target_alloc_working_area(target, progdata_size, &progdata) != ERROR_OK) { + LOG_ERROR("allocating working area failed"); + ret = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + goto out_noprogdata; + } + + blkcount = datalen / blksize; + + armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; + armv7m_info.core_mode = ARM_MODE_THREAD; + + init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* flash address */ + init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* block count */ + init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* block length */ + init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* progdata start */ + init_reg_param(®_params[4], "r4", 32, PARAM_OUT); /* progdata end */ + init_reg_param(®_params[5], "r5", 32, PARAM_OUT); /* FLEXSPI base */ + + buf_set_u32(reg_params[0].value, 0, 32, flashaddr); + buf_set_u32(reg_params[1].value, 0, 32, blkcount); + buf_set_u32(reg_params[2].value, 0, 32, blksize / sizeof(uint32_t)); + buf_set_u32(reg_params[3].value, 0, 32, progdata->address); + buf_set_u32(reg_params[4].value, 0, 32, + progdata->address + progdata->size); + buf_set_u32(reg_params[5].value, 0, 32, flexspi_info->io_base); + + ret = target_run_flash_async_algorithm(target, buf, blkcount, blksize, + 0, NULL, ARRAY_SIZE(reg_params), reg_params, + progdata->address, progdata->size, + algo->address, 0, &armv7m_info); + + if (ret == ERROR_FLASH_OPERATION_FAILED) { + end_address = buf_get_u32(reg_params[0].value, 0, 32); + + LOG_ERROR("Error writing flash at %08" PRIx32, end_address); + } else if (ret != ERROR_OK) { + LOG_ERROR("Error executing flash block programming algorithm"); + } + + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_params[2]); + destroy_reg_param(®_params[3]); + destroy_reg_param(®_params[4]); + + target_free_working_area(target, progdata); +out_noprogdata: + target_free_working_area(target, algo); +out_noalgo: + + return ret; +} + + static int erase_sector(struct flash_bank *bank, unsigned int sector) { struct target *target = bank->target; @@ -821,7 +798,7 @@ static int erase_sector(struct flash_bank *bank, unsigned int sector) uint8_t status; int ret; - LOG_DEBUG("reached"); + LOG_DEBUG("number %u", sector); ret = write_enable(bank); if (ret != ERROR_OK) @@ -1305,19 +1282,34 @@ static int fsl_flexspi_write(struct flash_bank *bank, const uint8_t *buffer, * thereof. */ if (offset % wrsize) { - ret = execute_page_program(bank, flexspi_info->dev.pprog_cmd, buffer, offset, + ret = program_page(bank, flexspi_info->dev.pprog_cmd, buffer, offset, offset % flexspi_info->dev.pagesize); if (ret != ERROR_OK) goto err; } + /* Attempt to program the entire block using on-chip algorithm */ + uint32_t blockwrlen = ALIGN_DOWN(count, wrsize); + LOG_DEBUG("Block program %" PRIu32 "B at 0x%08" PRIx32, blockwrlen, offset); + ret = program_block(bank, flexspi_info->dev.pprog_cmd, buffer, offset, + blockwrlen, wrsize); + if (ret == ERROR_OK) { + count -= blockwrlen; + offset += blockwrlen; + buffer += blockwrlen; + } else { + LOG_WARNING("Can't use block program; falling back to page program"); + return ret; + } + + /* Program by page whatever we couldn't program as a block */ while (count > 0) { if (count < wrsize) wrsize = count; - ret = execute_page_program(bank, flexspi_info->dev.pprog_cmd, - buffer, offset, wrsize); + ret = program_page(bank, flexspi_info->dev.pprog_cmd, buffer, offset, + wrsize); if (ret != ERROR_OK) goto err; diff --git a/src/flash/nor/fsl_flexspi.h b/src/flash/nor/fsl_flexspi.h new file mode 100644 index 0000000000..c199647276 --- /dev/null +++ b/src/flash/nor/fsl_flexspi.h @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Copyright (C) 2022 by Brandon Martin and Mothic Technologies LLC * + * mar...@mo... * + ***************************************************************************/ + +#include "spi.h" + +/* Make the BIT macro available from assembly */ +#ifndef BIT +# define BIT(x) (1 << (x)) +#endif + +/* These are the base addresses used on the IMXRT1020 */ +#define FLEXSPI_DEFAULT_IOBASE 0x402A8000 +#define FLEXSPI_LINEAR_AHBASE 0x60000000 +#define FLEXSPI_TX_FIFO_AHBASE 0x7F800000 +#define FLEXSPI_RX_FIFO_AHBASE 0x7FC00000 + +/* The documentation implies that these may be chip-specific tweakables */ +#define FLEXSPI_AHB_TX_BUFSZ 64 +#define FLEXSPI_AHB_RX_BUFSZ 1024 +#define FLEXSPI_IP_TX_FIFOSZ 128 +#define FLEXSPI_IP_RX_FIFOSZ 128 + +/* On-chip registers and fields */ +#define REG_MCR0 0x00 +#define MCR0_SWRESET BIT(0) +#define MCR0_MDIS BIT(1) +#define MCR0_ARDFEN BIT(6) +#define MCR0_ATDFEN BIT(7) + +#define REG_AHBCR 0x0C +#define AHBCR_ALIGNMENT(x) (((x) & 0x03) << 20) +#define AHBCR_READSZALIGN BIT(10) +#define AHBCR_READADDROPT BIT(6) +#define AHBCR_PREFETCHEN BIT(5) +#define AHBCR_BUFFERABLEEN BIT(4) +#define AHBCR_CACHABLEEN BIT(3) +#define AHBCR_APAREN BIT(0) + +#define REG_INTR 0x14 +#define INTR_IPCMDDONE BIT(0) +#define INTR_IPCMDGE BIT(1) +#define INTR_AHBCMDGE BIT(2) +#define INTR_IPCMDERR BIT(3) +#define INTR_AHBCMDERR BIT(4) +#define INTR_IPRXWA BIT(5) +#define INTR_IPTXWE BIT(6) +#define INTR_SCKSTOPBYRD BIT(8) +#define INTR_SCKSTOPBYWR BIT(9) +#define INTR_AHBBUSTTIMEOUT BIT(10) +#define INTR_SEQTIMEOUT BIT(11) +#define INTR_IPCMDSECUREVIO BIT(16) + +#define REG_LUTKEY 0x18 +#define LUTKEY_MAGIC 0x5AF05AF0 + +#define REG_LUTCR 0x1C +#define LUTCR_LOCK BIT(0) +#define LUTCR_UNLOCK BIT(1) +#define LUTCR_PROTECT BIT(2) + +#define REG_AHBRXBUF0CR0 0x20 +#define REG_AHBRXBUF1CR0 0x24 +#define REG_AHBRXBUF2CR0 0x28 +#define REG_AHBRXBUF3CR0 0x2C +#define AHBRXBUFNCR0_BUFSZ(x) (((x) & 0xFF) << 0) +#define AHBRXBUFNCR0_MSTRID(x) (((x) & 0x0F) << 16) +#define AHBRXBUFNCR0_PRIORITY(x) (((x) & 0x03) << 24) +#define AHBRXBUFNCR0_REGIONEN BIT(30) +#define AHBRXBUFNCR0_PREFETCHEN BIT(31) + +#define REG_FLSHA1CR0 0x60 +#define FLSHNNCR0_FLASHSZ(x) (((x) & 0x7FFFFF) << 0) + +#define REG_FLSHA1CR1 0x70 +#define FLSHNNCR1_TCSS(x) (((x) & 0x1F) << 0) +#define FLSHNNCR1_TCSH(x) (((x) & 0x1F) << 5) +#define FLSHNNCR1_WA BIT(10) +#define FLSHNNCR1_CAS(x) (((x) & 0x0F) << 11) +#define FLSHNNCR1_CSINTERVALUNIT BIT(15) +#define FLSHNNCR1_CSINTERVAL(x) (((x) & 0xFFFF) << 16) + +#define REG_FLSHA1CR2 0x80 +#define FLSHNNCR2_ARDSEQID(x) (((x) & 0x0F) << 0) +#define FLSHNNCR2_ARDSEQNUM(x) (((x) & 0x07) << 5) +#define FLSHNNCR2_AWRSEQID(x) (((x) & 0x0F) << 8) +#define FLSHNNCR2_AWRSEQNUM(x) (((x) & 0x07) << 13) +#define FLSHNNCR2_AWRWAIT(x) (((x) & 0x0FFF) << 16) +#define FLSHNNCR2_AWRWAITUNIT(x) (((x) & 0x07) << 28) +#define AWRWAITUNIT_2AHB 0 +#define AWRWAITUNIT_8AHB 1 +#define AWRWAITUNIT_32AHB 2 +#define AWRWAITUNIT_128AHB 3 +#define AWRWAITUNIT_512AHB 4 +#define AWRWAITUNIT_2048AHB 5 +#define AWRWAITUNIT_8192AHB 6 +#define AWRWAITUNIT_32768AHB 7 +#define FLSHNNCR2_CLRINSTRPTR BIT(31) + +#define REG_FLSHCR4 0x94 +#define FLSHCR4_WMOPT1 BIT(0) +#define FLSHCR4_WMENA BIT(2) +#define FLSHCR4_WMENB BIT(3) +#define FLSHCR4_PAR_WM(x) (((x) & 0x03) << 9) +#define FLSHCR4_PAR_ADDR_ADJ_DIS BIT(11) + +#define REG_IPCR0 0xA0 +#define IPCR0_SFAR(x) (x) + +#define REG_IPCR1 0xA4 +#define IPCR1_IDATASZ(x) (((x) & 0xFFFF) << 0) +#define IPCR1_ISEQID(x) (((x) & 0x0F) << 16) +#define IPCR1_ISEQNUM(x) (((x) & 0x0F) << 24) +#define IPCR1_IPAREN BIT(31) + +#define REG_IPCMD 0xB0 +#define IPCMD_TRG BIT(0) + +#define REG_IPRXFCR 0xB8 +#define IPRXFCR_CLRIPRXF BIT(0) +#define IPRXFCR_RXDMAEN BIT(1) +#define IPRXFCR_RXWMRK(x) (((x) & 0x0F) << 2) + +#define REG_IPTXFCR 0xBC +#define IPTXFCR_CLRIPTXF BIT(0) +#define IPTXFCR_TXDMAEN BIT(1) +#define IPTXFCR_TXWMRK(x) (((x) & 0x0F) << 2) + +#define REG_STS1 0xE4 + +#define REG_RFDR 0x100 +#define REG_TFDR 0x180 + +#define REG_LUT_BASE 0x200 +#define REG_LUT(x) (REG_LUT_BASE + (x) * 4) + +/* + * This LUT sequence ID is used during probe to read flash IDs and then is + * left configured so that the FLEXSPI can provide the usual linear + * memory-mapped access to the attached serial flash + * + * The LUT sequence ID 0 is the default for FlexSPI NOR (and NAND?) boot + * and is used by every example from Freescale/NXP that I've ever seen for AHB + * reads, though it doesn't strictly have to be. + */ +#define LUTNUM_AHB_READ 0 + +/* + * This LUT sequence ID is used to read flash status since it's a common + * thing to have to do interleaved with other actions + * + * The LUT sequence ID 1 is pretty much universally used for this purpose + * throughout Freescale/NXP's example/HAL code, and we at least attempt to use + * it in a compatible way. + */ +#define LUTNUM_READ_STATUS 1 + +/* + * This LUT sequence ID is used to perform write enable since it's also a + * common thing to have to do interleaved with other actions + * + * Like with read status, LUT ID 3 seems to be used for this pretty much + * everywhere at least for NOR flash. + */ +#define LUTNUM_WRITE_ENABLE 3 + +/* + * The usual LUT sequence ID to be used by the driver after probing for + * general activities other than reading status and performing write enable + * + * Other LUT sequence numbers will not be touched and can be used by + * application code without impeding operating by the driver without controller + * re-initialization if some other basic conditions are met. + * + * The LUT sequence number 10 is not used by boot procedures nor the Freescale + * sample code + */ +#define LUTNUM_DRV 10 + +/* Instruction set for the LUT register (SDR only) */ +#define OPCODE_STOP 0 +#define OPCODE_CMD 1 +#define OPCODE_RADDR 2 +#define OPCODE_CADDR 3 +#define OPCODE_MODE1 4 +#define OPCODE_MODE2 5 +#define OPCODE_MODE4 6 +#define OPCODE_MODE8 7 +#define OPCODE_WRITE 8 +#define OPCODE_READ 9 +#define OPCODE_LEARN 10 +#define OPCODE_DATSZ 11 +#define OPCODE_DUMMY 12 +#define OPCODE_JMP_ON_CS 31 + -- |
From: Richard A. <rs...@gm...> - 2025-05-25 02:42:11
|
Great to hear v1.0.0 is coming. > I invite you all to report any feature still pending in Gerrit that you absolutely want to have in v1.0.0. I'd love to get the sparse, lossless gmon encoder reviewed and merged. Combined with gprof, this supports line-based profiling accurate to +/-2 instructions or better, regardless of firmware size or address space range. It's the patch stack with https://review.openocd.org/c/openocd/+/8739 at the top. -Richard |
From: Tomas V. <to...@us...> - 2025-05-24 11:53:40
|
Martin, On 24/05/2025 04:58, Brandon Martin wrote: > It would be handy for the FLEXSPI if there were target events for > non-GDB initiated flash erase start/end and write start/end since it > would allow deferring disabling of watchdogs, which are chip-specific, > to the relevant TCL scripts. Is that something that folks would be > amenable to me adding? Does that already exist (I don't see it)? Please be aware of *12.2 Preparing a Target before Flash Programming *""" The target device should be in well defined state before the flash programming begins. Always issue reset init before Flash Programming Commands. ... If you use Programming using GDB, the target is prepared automatically in the event gdb-flash-erase-start The Tcl script program calls reset init explicitly. * """ *So the Tcl event which should be issued before flash erase/write is reset-init. With the exception of targets with totally screwed reset. * * > > The Kinetis flash driver, at least, already has to handle some of > this. It has multiple "watchdog algorithms" and tries to match them up > heuristically. It can reasonably do this to some degree because all > Kinetis parts have a similar memory map, and there are only a few > different watchdogs across the whole line. Unfortunately the Kinetis watchdog is so strict in checking the time between writes in the switch-off sequence that we have to run a target algo to meet the sequence timing. If iMXRT has a similar watchdog then Tcl target memory writes will not work. > > The FLEXSPI is used in parts ranging from the smallest of the iMXRT > series (Cortex-M7) all the way up to some rather large iMX application > processors (multi-core Cortex-A7x). While the current driver has only > been tested on IMXRT1020 (though probably works on all of the iMXRT > parts), I'd like to avoid getting into unrelated, chip-specific stuff > that is known to not be chip-agnostic within the flash driver code > itself if possible. > > It does look like all of the iMXRT parts have the same set of > watchdogs mapped in the same places, so if we knowingly restrict the > driver to just iMXRT (which are probably the most useful parts in the > context of openocd), then this may be a non-issue. > -- > Brandon Martin > I agree it would be nice to have the watchdog handling optional. For the beginning one option no wdog handling, the second iMXRT related. Tomas |
From: Brandon M. <lis...@mo...> - 2025-05-24 03:07:29
|
It would be handy for the FLEXSPI if there were target events for non-GDB initiated flash erase start/end and write start/end since it would allow deferring disabling of watchdogs, which are chip-specific, to the relevant TCL scripts. Is that something that folks would be amenable to me adding? Does that already exist (I don't see it)? The Kinetis flash driver, at least, already has to handle some of this. It has multiple "watchdog algorithms" and tries to match them up heuristically. It can reasonably do this to some degree because all Kinetis parts have a similar memory map, and there are only a few different watchdogs across the whole line. The FLEXSPI is used in parts ranging from the smallest of the iMXRT series (Cortex-M7) all the way up to some rather large iMX application processors (multi-core Cortex-A7x). While the current driver has only been tested on IMXRT1020 (though probably works on all of the iMXRT parts), I'd like to avoid getting into unrelated, chip-specific stuff that is known to not be chip-agnostic within the flash driver code itself if possible. It does look like all of the iMXRT parts have the same set of watchdogs mapped in the same places, so if we knowingly restrict the driver to just iMXRT (which are probably the most useful parts in the context of openocd), then this may be a non-issue. -- Brandon Martin |
From: Brandon M. <lis...@mo...> - 2025-05-24 03:07:19
|
On 5/23/25 06:16, Antonio Borneo wrote: > Said that, I invite you all to report any feature still pending in > Gerrit that you absolutely want to have in v1.0.0. It would be nice if the flexspi support I've had pending could get merged. I did recently submit a revised patch addressing all outstanding review comments for the base write/erase support which is enough for it to be functional. I also have a patch available that drastically (factor of 5 or so) improves write throughput, but it currently has -isms specific to the imxrt1020 due to watchdogs which probably makes it unsuitable for merging at this time. See followup / unrelated to release question. I can attempt to address them if desired, but having some support in 1.0.0 would be great even if it doesn't have these performance improvements. -- Brandon Martin |
From: <Lia...@mi...> - 2025-05-23 20:08:22
|
Hello, we see that an RC1 is coming soon. We have some pull requests open for drivers that will probably not make it in on time, however the configuration files for the target is ready and can be used with already upstreamed drivers such as Olimex, etc for software debug. What we would like to do is to try get the target configuration file in and drop the patches for driver support. What would be the best way to do this? Currently Conor Paxton has patches for all the drivers/ configuration files (8563<https://review.openocd.org/c/openocd/+/8563> and 8561<https://review.openocd.org/c/openocd/+/8561>). Should we abandon these and create a new patch with just the target configuration file? Thank you in advance for any advice offered. Best regards, Liam. |
From: <Lia...@mi...> - 2025-05-23 16:17:46
|
Hello, we see that an RC1 is coming soon. We have some pull requests open for drivers that will probably not make it in on time, however the configuration files for the target is ready and can be used with already upstreamed drivers such as Olimex, etc for software debug. What we would like to do is to try get the target configuration file in and drop the patches for driver support. What would be the best way to do this? Currently Conor Paxton has patches for all the drivers/ configuration files (8563<https://review.openocd.org/c/openocd/+/8563> and 8561<https://review.openocd.org/c/openocd/+/8561>). Should we abandon these and create a new patch with just the target configuration file? Thank you in advance for any advice offered. Best regards, Liam. (apologies if this is a duplication, issue with mail client) |
From: Liviu I. <il...@li...> - 2025-05-23 13:48:23
|
> On 23 May 2025, at 13:16, Antonio Borneo <bor...@gm...> wrote: > > Hello, > > we are going to tag OpenOCD v1.0.0-rc1 in around one month. f I remember right, the Raspberry Pico project also had an openocd fork. It would be great to also upstream the changes in that fork, since the pico is a very popular platform. I Regards, Liviu |
From: Antonio B. <bor...@gm...> - 2025-05-23 10:16:54
|
Hello, we are going to tag OpenOCD v1.0.0-rc1 in around one month. It will follow a period of code freeze, during which only patches for bug fixes will be merged. The release v1.0.0 is expected before the end of the year. Why v1.0.0 ? Because OpenOCD is 20 years old, and at such an age it's mature enough for a cool major release. Because today we have already merged 996 commits since last release v0.12.0 (2023-01-14), and it's time to focus on tests and fixes. Because it's summer and old bugs get hotter, so time to fix them. Because, ... feel free to add your personal reason to this list! ;-) Said that, I invite you all to report any feature still pending in Gerrit that you absolutely want to have in v1.0.0. Regards, Antonio |
From: <ge...@op...> - 2025-05-23 06:48:01
|
This is an automated email from Gerrit. "Anatoly P <ana...@sy...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8932 -- gerrit commit 3f880b317973a9a41bed02f4ccb41ae38ed70ac6 Author: Parshintsev Anatoly <ana...@sy...> Date: Thu May 22 18:30:23 2025 +0300 server: track asynchronous and synchronous shutdown requests separately (NFC) Change-Id: Ic34d6e90919d18616207fe38528ca4d190e9d12a Signed-off-by: Parshintsev Anatoly <ana...@sy...> diff --git a/src/openocd.c b/src/openocd.c index 3fbece3955..4e0b678c96 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -312,9 +312,12 @@ static int openocd_thread(int argc, char *argv[], struct command_context *cmd_ct ret = server_loop(cmd_ctx); int last_signal = server_quit(); - if (last_signal != ERROR_OK) - return last_signal; + /* warning: here we return either a signal number of ERROR_OK / ERROR_FAIL + * status. This works, because ERROR_OK is zero an ERROR_FAIL is negative */ + assert(ERROR_FAIL < 0); + if (last_signal != 0) + return last_signal; if (ret != ERROR_OK) return ERROR_FAIL; return ERROR_OK; diff --git a/src/server/server.c b/src/server/server.c index c9499f9395..5bd122090b 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -37,17 +37,16 @@ static struct service *services; -enum shutdown_reason { - CONTINUE_MAIN_LOOP, /* stay in main event loop */ - SHUTDOWN_REQUESTED, /* set by shutdown command; exit the event loop and quit the debugger */ - SHUTDOWN_WITH_ERROR_CODE, /* set by shutdown command; quit with non-zero return code */ - SHUTDOWN_WITH_SIGNAL_CODE /* set by sig_handler; exec shutdown then exit with signal as return code */ -}; - -static volatile sig_atomic_t shutdown_openocd = CONTINUE_MAIN_LOOP; +/* this *flag* indicates that we have a pending shutdown request because of an + * asynchronous event such as signal or WM_QUIT in the message queue for + * windows */ +static volatile sig_atomic_t async_shutdown_requested; /* store received signal to exit application by killing ourselves */ static volatile sig_atomic_t last_signal; +bool sync_shutdown_requested; +bool sync_shutdown_reports_error; + /* set the polling period to 100ms */ static int polling_period = 100; @@ -439,7 +438,7 @@ int server_loop(struct command_context *command_context) LOG_ERROR("couldn't set SIGPIPE to SIG_IGN"); #endif - while (shutdown_openocd == CONTINUE_MAIN_LOOP) { + while (!openocd_is_shutdown_pending()) { /* monitor sockets for activity */ fd_max = 0; FD_ZERO(&read_fds); @@ -569,7 +568,7 @@ int server_loop(struct command_context *command_context) service->type == CONNECTION_STDINOUT) { /* if connection uses a pipe then * shutdown openocd on error */ - shutdown_openocd = SHUTDOWN_REQUESTED; + sync_shutdown_requested = true; } remove_connection(service, c); LOG_INFO("dropped '%s' connection", @@ -587,23 +586,24 @@ int server_loop(struct command_context *command_context) MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) - shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE; + async_shutdown_requested = true; } #endif } /* when quit for signal or CTRL-C, run (eventually user implemented) "shutdown" */ - if (shutdown_openocd == SHUTDOWN_WITH_SIGNAL_CODE) + if (async_shutdown_requested) command_run_line(command_context, "shutdown"); - return shutdown_openocd == SHUTDOWN_WITH_ERROR_CODE ? ERROR_FAIL : ERROR_OK; + return sync_shutdown_reports_error ? ERROR_FAIL : ERROR_OK; } static void sig_handler(int sig) { /* store only first signal that hits us */ - if (shutdown_openocd == CONTINUE_MAIN_LOOP) { - shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE; + if (!async_shutdown_requested) { + assert(sig >= SIG_ATOMIC_MIN && sig <= SIG_ATOMIC_MAX); + async_shutdown_requested = true; last_signal = sig; LOG_DEBUG("Terminating on Signal %d", sig); } else @@ -614,7 +614,7 @@ static void sig_handler(int sig) #ifdef _WIN32 BOOL WINAPI control_handler(DWORD ctrl_type) { - shutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE; + async_shutdown_requested = true; return TRUE; } #else @@ -703,7 +703,7 @@ int server_quit(void) #ifdef _WIN32 SetConsoleCtrlHandler(control_handler, FALSE); - return ERROR_OK; + return 0; #endif /* return signal number so we can kill ourselves */ @@ -751,7 +751,7 @@ int connection_read(struct connection *connection, void *data, int len) bool openocd_is_shutdown_pending(void) { - return shutdown_openocd != CONTINUE_MAIN_LOOP; + return sync_shutdown_requested || async_shutdown_requested; } /* tell the server we want to shut down */ @@ -759,13 +759,13 @@ COMMAND_HANDLER(handle_shutdown_command) { LOG_USER("shutdown command invoked"); - shutdown_openocd = SHUTDOWN_REQUESTED; + sync_shutdown_requested = true; command_run_line(CMD_CTX, "_run_pre_shutdown_commands"); if (CMD_ARGC == 1) { if (!strcmp(CMD_ARGV[0], "error")) { - shutdown_openocd = SHUTDOWN_WITH_ERROR_CODE; + sync_shutdown_reports_error = true; return ERROR_FAIL; } } -- |
From: <ge...@op...> - 2025-05-22 08:31:29
|
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/+/8931 -- gerrit commit 58ae6d8a17f4c39c3f0798e9df845df7eeaa3b7e Author: Antonio Borneo <bor...@gm...> Date: Thu May 22 02:02:19 2025 +0200 helper: configuration: check for empty search dirs The function find_file() is supposed to be called when the search dirs in 'script_search_dirs' has already been populated. This is not the case when the command 'ocd_find' is used in one of the embedded scripts 'startup.tcl'. It then triggers SIGSEGV. Check for 'script_search_dirs' and eventually skip searching in the dirs. Change-Id: I9e75a8739c94de72041fb64487910d60dffcb2bd signed-off-by: antonio borneo <bor...@gm...> diff --git a/src/helper/configuration.c b/src/helper/configuration.c index 16732eb3dd..447b0dfefa 100644 --- a/src/helper/configuration.c +++ b/src/helper/configuration.c @@ -71,17 +71,18 @@ char *find_file(const char *file) full_path = alloc_printf("%s", file); fp = fopen(full_path, mode); - while (!fp) { - free(full_path); - full_path = NULL; - dir = *search_dirs++; + if (script_search_dirs) + while (!fp) { + free(full_path); + full_path = NULL; + dir = *search_dirs++; - if (!dir) - break; + if (!dir) + break; - full_path = alloc_printf("%s/%s", dir, file); - fp = fopen(full_path, mode); - } + full_path = alloc_printf("%s/%s", dir, file); + fp = fopen(full_path, mode); + } if (fp) { fclose(fp); -- |
From: <ge...@op...> - 2025-05-21 17:57:10
|
This is an automated email from Gerrit. "Lucien Buchmann <luc...@du...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8930 -- gerrit commit f53ef91274c8d702db49382634534e15bf1b9f0e Author: Lucien Dufour <luc...@du...> Date: Wed May 21 19:38:26 2025 +0200 target: Fix keep_alive() calls in target_wait_state() Previously, after 500ms, the keep_alive() function was called continuously until the timeout was reached. Change-Id: I99b6bb60c0a36ab976619fbadfcb1d5e674b5ad2 Signed-off-by: Lucien Dufour <luc...@du...> diff --git a/src/target/target.c b/src/target/target.c index 6653c381c0..be1134ffed 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -3212,46 +3212,45 @@ COMMAND_HANDLER(handle_wait_halt_command) return target_wait_state(target, TARGET_HALTED, ms); } -/* wait for target state to change. The trick here is to have a low - * latency for short waits and not to suck up all the CPU time - * on longer waits. - * - * After 500ms, keep_alive() is invoked +/* Wait for the target's state to match the desired state. + * The trick here is to have a low latency for short waits and + * not to suck up all the CPU time on longer waits. + * Every 500ms, a keep_alive() is invoked to avoid GDB timeouts. */ -int target_wait_state(struct target *target, enum target_state state, unsigned int ms) +int target_wait_state(struct target *target, enum target_state state, unsigned int timeout_ms) { int retval; - int64_t then = 0, cur; bool once = true; + int64_t since = timeval_ms(); + int64_t last_alive = timeval_ms(); + int64_t now = timeval_ms(); - for (;;) { + while ((now - since) < (int64_t)timeout_ms) { retval = target_poll(target); if (retval != ERROR_OK) return retval; if (target->state == state) - break; - cur = timeval_ms(); + return ERROR_OK; + if (once) { once = false; - then = timeval_ms(); LOG_DEBUG("waiting for target %s...", nvp_value2name(nvp_target_state, state)->name); } - if (cur - then > 500) { + now = timeval_ms(); + if (now - last_alive > 500) { keep_alive(); + last_alive = timeval_ms(); if (openocd_is_shutdown_pending()) return ERROR_SERVER_INTERRUPTED; } - - if ((cur-then) > ms) { - LOG_ERROR("timed out while waiting for target %s", - nvp_value2name(nvp_target_state, state)->name); - return ERROR_FAIL; - } } - return ERROR_OK; + LOG_ERROR("timed out (%d ms) while waiting for target %s", + timeout_ms, + nvp_value2name(nvp_target_state, state)->name); + return ERROR_FAIL; } COMMAND_HANDLER(handle_halt_command) -- |
From: <ge...@op...> - 2025-05-21 13:23:08
|
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/+/8929 -- gerrit commit cbce1a93ed2ce90f1273bf4c181c770488f9c217 Author: Antonio Borneo <bor...@gm...> Date: Wed May 21 15:19:28 2025 +0200 startup.tcl: extend the file search in vendor folders To help the dispatching of configuration files in vendor specific folders, extend the search of files in vendor folders too. This feature should be removed later on to prevent clashing on files with the same name. Change-Id: If4793fef27dc570d5df4ff4d77a5e36004f394f6 Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl index e6e76e68fd..112815299c 100644 --- a/src/helper/startup.tcl +++ b/src/helper/startup.tcl @@ -7,7 +7,8 @@ # Try flipping / and \ to find file if the filename does not # match the precise spelling -proc find {filename} { +# lappend _telnet_autocomplete_skip _find_internal +proc _find_internal {filename} { if {[catch {ocd_find $filename} t]==0} { return $t } @@ -20,6 +21,23 @@ proc find {filename} { # make sure error message matches original input string return -code error "Can't find $filename" } + +proc find {filename} { + if {[catch {_find_internal $filename} t]==0} { + return $t + } + + # Check in vendor specific folder + foreach v {nordic ti st} { + regsub {([/\\])([^/\\]*$)} $filename "\\1$v\\1\\2" f + if {[catch {_find_internal $f} t]==0} { + echo "WARNING: '$filename' is deprecated, use '$f' instead" + return $t + } + } + + return -code error "Can't find $filename" +} add_usage_text find "<file>" add_help_text find "print full path to file according to OpenOCD search rules" -- |
From: <ge...@op...> - 2025-05-20 15:52:51
|
This is an automated email from Gerrit. "Lucien Buchmann <luc...@du...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8928 -- gerrit commit 768722fcc2fad68c7687119b45a685d36106abb4 Author: Lucien Dufour <luc...@du...> Date: Tue May 20 17:39:19 2025 +0200 tcl/target: Add support for TMS570LS1xxx Added support for TMS570LS1xxx series parts. This uses the existing ti_tms570.cfg as parent. Change-Id: I40567bfb8dc052532807df68ef3d42f8e7a8ecf4 Signed-off-by: Lucien Dufour <luc...@du...> diff --git a/tcl/target/ti_tms570ls1xxx.cfg b/tcl/target/ti_tms570ls1xxx.cfg new file mode 100644 index 0000000000..3c25777578 --- /dev/null +++ b/tcl/target/ti_tms570ls1xxx.cfg @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# TMS570LS1114, TMS570LS1115 +# TMS570LS1224, TMS570LS1225, TMS570LS1227 +set DAP_TAPID 0x0B95502F +set JRC_TAPID 0x0B95502F + +source [find target/ti_tms570.cfg] -- |
From: <ge...@op...> - 2025-05-20 09:35:07
|
This is an automated email from Gerrit. "Anatoly P <ana...@sy...>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8927 -- gerrit commit 4f24554c2908319df0f968ffe8479e84e17e3720 Author: Parshintsev Anatoly <ana...@sy...> Date: Tue May 20 10:10:43 2025 +0300 server: global state updated by signal handlers should have volatile atomic lock-free type Signal handlers currently violate both C language and POSIX requirements: 1. To avoid undefined behavior (UB), variables accessed or modified by signal handlers be of atomic lock-free type. 2. The respected variables should be marked as volatile. 3. Signal handlers may only call a very limited subset of standard library functions. 4. Additionally, POSIX restricts signal handlers to signal-safe functions. This patch addresses the first two issues on platformats that support lock-free atomic access to int. For platforms that do not support lock-free atomic access to int we just mark the respected variables as volatile and hope for the best. Items 3 and 4 must be handled separately but are outside the scope of this change. Change-Id: I9c344e87bab9eefe7d99b0aad300a3ef4712df51 Signed-off-by: Parshintsev Anatoly <ana...@sy...> diff --git a/src/server/server.c b/src/server/server.c index 0649ec942b..0be1d303e2 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -25,6 +25,7 @@ #include "telnet_server.h" #include "ipdbg.h" +#include <stdatomic.h> #include <signal.h> #ifdef HAVE_NETDB_H @@ -43,10 +44,18 @@ enum shutdown_reason { SHUTDOWN_WITH_ERROR_CODE, /* set by shutdown command; quit with non-zero return code */ SHUTDOWN_WITH_SIGNAL_CODE /* set by sig_handler; exec shutdown then exit with signal as return code */ }; -static enum shutdown_reason shutdown_openocd = CONTINUE_MAIN_LOOP; +#if (ATOMIC_INT_LOCK_FREE == 2) +typedef volatile atomic_int signal_updated_int_t; +#else +// For platforms that do not have lock-free atomic int type we just fall-back +// to good old `volatile int` and hope for the best +typedef volatile int signal_updated_int_t; +#endif + +static signal_updated_int_t shutdown_openocd = CONTINUE_MAIN_LOOP; /* store received signal to exit application by killing ourselves */ -static int last_signal; +static signal_updated_int_t last_signal; /* set the polling period to 100ms */ static int polling_period = 100; -- |
From: <ge...@op...> - 2025-05-19 15:19:19
|
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/+/8926 -- gerrit commit eba2e7a04d2328748ffbe3d817c2b7c56e35043b Author: Tomas Vanek <va...@fb...> Date: Mon May 19 17:10:00 2025 +0200 rtos/hwthread: use printf format specifier instead of typecast. Change-Id: I62e3a0faebd915615f6b72a456667c49970a4091 Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c index 4156236c68..0fca159737 100644 --- a/src/rtos/hwthread.c +++ b/src/rtos/hwthread.c @@ -204,8 +204,8 @@ static int hwthread_update_threads(struct rtos *rtos) else rtos->current_thread = threadid_from_target(target); - LOG_TARGET_DEBUG(target, "current_thread=%i, threads_found=%d", - (int)rtos->current_thread, threads_found); + LOG_TARGET_DEBUG(target, "current_thread=%" PRId64 ", threads_found=%d", + rtos->current_thread, threads_found); return 0; } -- |
From: <ge...@op...> - 2025-05-19 14:47:38
|
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/+/8923 -- gerrit commit d21f25cdd3be8f918b43bf535dd68740971a0d74 Author: Tomas Vanek <va...@fb...> Date: Mon May 19 16:00:52 2025 +0200 doc: list target unavailable state Fixes: 8911: target: Add TARGET_UNAVAILABLE state | https://review.openocd.org/c/openocd/+/8911 Change-Id: I6d152aea5bb449f79fd0f829252442b8b9f8ed9c Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/doc/openocd.texi b/doc/openocd.texi index ca357c7802..27ed46b920 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5439,7 +5439,8 @@ Displays the current target state: @code{debug-running}, @code{halted}, @code{reset}, -@code{running}, or @code{unknown}. +@code{running}, +@code{unavailable} or @code{unknown}. (Also, @pxref{eventpolling,,Event Polling}.) @end deffn -- |
From: <ge...@op...> - 2025-05-19 14:47:33
|
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/+/8925 -- gerrit commit 644c98357558a51dbb979d0222f5b1704dd93619 Author: Tomas Vanek <va...@fb...> Date: Mon May 19 16:29:26 2025 +0200 target, server, rtos: introduce and use target_is_available() helper Use the new helper function instead of TARGET_UNAVAILABLE tests imported from riscv-collab. Later we can extend TARGET_UNAVAILABLE testing by simply replacing most of target_was_examined() tests by target_is_available() Change-Id: If024cc2e8ed02dbcb68ca660dfd929882aff1035 Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c index 5c6c45f78f..4156236c68 100644 --- a/src/rtos/hwthread.c +++ b/src/rtos/hwthread.c @@ -105,8 +105,7 @@ static int hwthread_update_threads(struct rtos *rtos) foreach_smp_target(head, target->smp_targets) { struct target *curr = head->target; - if (!target_was_examined(curr) || - curr->state == TARGET_UNAVAILABLE) + if (!target_is_available(curr)) continue; ++thread_list_size; @@ -131,8 +130,7 @@ static int hwthread_update_threads(struct rtos *rtos) foreach_smp_target(head, target->smp_targets) { struct target *curr = head->target; - if (!target_was_examined(curr) || - curr->state == TARGET_UNAVAILABLE) + if (!target_is_available(curr)) continue; threadid_t tid = threadid_from_target(curr); diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 580a96d98f..512a7e7f7b 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -159,11 +159,11 @@ struct target *get_available_target_from_connection(struct connection *connectio { struct gdb_service *gdb_service = connection->service->priv; struct target *target = gdb_service->target; - if (target->state == TARGET_UNAVAILABLE && target->smp) { + if (!target_is_available(target) && target->smp) { struct target_list *tlist; foreach_smp_target(tlist, target->smp_targets) { struct target *t = tlist->target; - if (t->state != TARGET_UNAVAILABLE) + if (target_is_available(t)) return t; } /* If we can't find an available target, just return the @@ -3043,7 +3043,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p if (parse[0] == 'c') { gdb_running_type = 'c'; - if (target->state == TARGET_UNAVAILABLE) { + if (!target_is_available(target)) { struct target *available_target = get_available_target_from_connection(connection); if (target == available_target) { LOG_DEBUG("All targets for this gdb connection " @@ -3188,7 +3188,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p return true; } - if (ct->state == TARGET_UNAVAILABLE) { + if (!target_is_available(ct)) { LOG_TARGET_INFO(ct, "Target is unavailable, so cannot be stepped. " "Pretending to gdb that it is running until it's available again."); retval = ERROR_FAIL; diff --git a/src/target/target.h b/src/target/target.h index b850b49cf3..89dd7be4aa 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -434,6 +434,13 @@ static inline bool target_was_examined(const struct target *target) return target->examined; } +/** @returns @c true if target is available: was examined + * and is not in TARGET_UNAVAILABLE state */ +static inline bool target_is_available(const struct target *target) +{ + return target_was_examined(target) && target->state != TARGET_UNAVAILABLE; +} + /** Sets the @c examined flag for the given target. */ /** Use in target->type->examine() after one-time setup is done. */ static inline void target_set_examined(struct target *target) -- |
From: <ge...@op...> - 2025-05-19 14:47:33
|
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/+/8924 -- gerrit commit e730393dacd6725db640b548b44daba8a3ace836 Author: Tomas Vanek <va...@fb...> Date: Mon May 19 16:05:50 2025 +0200 server/gdb_server: minor fixes of unavailable target handling Decreased log message severity. Fixed comment typo. Change-Id: I1f76ba1e3ee6710ce1ec4cdf95c6473797b57c4c Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index d596a76e01..580a96d98f 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -172,7 +172,7 @@ struct target *get_available_target_from_connection(struct connection *connectio return target; } -/** Return true iff the given connection includes the given target. */ +/** Return true if the given connection includes the given target. */ static bool gdb_connection_includes_target(struct connection *connection, struct target *target) { struct gdb_service *gdb_service = connection->service->priv; @@ -3189,7 +3189,7 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p } if (ct->state == TARGET_UNAVAILABLE) { - LOG_TARGET_ERROR(ct, "Target is unavailable, so cannot be stepped. " + LOG_TARGET_INFO(ct, "Target is unavailable, so cannot be stepped. " "Pretending to gdb that it is running until it's available again."); retval = ERROR_FAIL; } else { -- |
From: <ge...@op...> - 2025-05-19 13:28:07
|
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/+/8922 -- gerrit commit 90f7665e221b93eff1b271d80b847c9f74bba797 Author: Antonio Borneo <bor...@gm...> Date: Mon May 19 15:23:23 2025 +0200 server: gdb_server: use a macro for CTRL-C value The numeric value '3' for the ASCII character CTRL-C is not immediately readable, even if the lines that follow explicitly mention CTRL-C. Use the same macro present in `telnet_server.c` to replace the numeric value. Change-Id: Iaf4296b1f0e384f8122d8a4875cad17e8ddaf66a Signed-off-by: Antonio Borneo <bor...@gm...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index bd00feb490..085058f4f3 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -50,6 +50,8 @@ * found in most modern embedded processors. */ +#define CTRL(c) ((c) - '@') + enum gdb_output_flag { /* GDB doesn't accept 'O' packets */ GDB_OUTPUT_NO, @@ -434,7 +436,7 @@ static int gdb_put_packet_inner(struct connection *connection, gdb_putback_char(connection, reply); LOG_DEBUG("Unexpected start of new packet"); break; - } else if (reply == 0x3) { + } else if (reply == CTRL('C')) { /* do not discard Ctrl-C */ gdb_putback_char(connection, reply); break; @@ -486,7 +488,7 @@ static int gdb_put_packet_inner(struct connection *connection, gdb_con->output_flag = GDB_OUTPUT_NO; gdb_log_incoming_packet(connection, "-"); LOG_WARNING("negative reply, retrying"); - } else if (reply == 0x3) { + } else if (reply == CTRL('C')) { gdb_con->ctrl_c = true; gdb_log_incoming_packet(connection, "<Ctrl-C>"); retval = gdb_get_char(connection, &reply); @@ -696,7 +698,7 @@ static int gdb_get_packet_inner(struct connection *connection, gdb_log_incoming_packet(connection, "-"); LOG_WARNING("negative acknowledgment, but no packet pending"); break; - case 0x3: + case CTRL('C'): gdb_log_incoming_packet(connection, "<Ctrl-C>"); gdb_con->ctrl_c = true; *len = 0; -- |
From: <ge...@op...> - 2025-05-19 05:05: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/+/8921 -- gerrit commit ea98a805b5510b297bef87c7c38988b149f94f0f Author: Tim Newsome <ti...@si...> Date: Thu Oct 13 13:29:15 2022 -0700 target/breakpoints: Do not add/remove bp/wp on unavailable targets Imported from https://github.com/riscv-collab/riscv-openocd/pull/767 Extracted part of target/riscv: Don't resume unavailable harts. Change-Id: Id6617230cfdadf93ba402e60fb704bdfe7af5c1e Signed-off-by: Tim Newsome <ti...@si...> diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index a080416291..eb50587153 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -78,7 +78,7 @@ static int breakpoint_add_internal(struct target *target, reason = "resource not available"; goto fail; case ERROR_TARGET_NOT_HALTED: - reason = "target running"; + reason = "target not halted"; goto fail; default: reason = "unknown reason"; @@ -210,16 +210,12 @@ int breakpoint_add(struct target *target, unsigned int length, enum breakpoint_type type) { - if (target->smp) { + if (target->smp && type == BKPT_HARD) { 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 (curr->state == TARGET_UNAVAILABLE) + continue; int retval = breakpoint_add_internal(curr, address, length, type); if (retval != ERROR_OK) return retval; @@ -241,6 +237,8 @@ int context_breakpoint_add(struct target *target, foreach_smp_target(head, target->smp_targets) { struct target *curr = head->target; + if (curr->state == TARGET_UNAVAILABLE) + continue; int retval = context_breakpoint_add_internal(curr, asid, length, type); if (retval != ERROR_OK) return retval; @@ -263,6 +261,8 @@ int hybrid_breakpoint_add(struct target *target, foreach_smp_target(head, target->smp_targets) { struct target *curr = head->target; + if (curr->state == TARGET_UNAVAILABLE) + continue; int retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type); if (retval != ERROR_OK) return retval; @@ -542,7 +542,7 @@ static int watchpoint_add_internal(struct target *target, target_addr_t address, reason = "resource not available"; goto bye; case ERROR_TARGET_NOT_HALTED: - reason = "target running"; + reason = "target not halted"; goto bye; default: reason = "unrecognized error"; @@ -573,6 +573,8 @@ int watchpoint_add(struct target *target, target_addr_t address, foreach_smp_target(head, target->smp_targets) { struct target *curr = head->target; + if (curr->state == TARGET_UNAVAILABLE) + continue; int retval = watchpoint_add_internal(curr, address, length, rw, value, mask); if (retval != ERROR_OK) return retval; -- |
From: <ge...@op...> - 2025-05-18 20:04:34
|
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/+/8920 -- gerrit commit d4a8f592f7583c87fdb858f9d218b95caa3421bb Author: Tomas Vanek <va...@fb...> Date: Sun May 18 21:25:35 2025 +0200 server/gdb_server: do not discard Ctrl-C if _DEBUG_GDB_IO_ GDB server debug logging eat Ctrl-C when gdb user issues interrupt in time of communication between OpenOCD and gdb. E.g. Ctrl-C after `next` gdb command taking many gdb remote protocol $vCont;s (steps) Change-Id: I4a65446a9bb25a28e50566607b3dec116fa7d2cd Suggested-by: Tim Newsome <ti...@si...> Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 71b7c7764a..bd00feb490 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -434,6 +434,10 @@ static int gdb_put_packet_inner(struct connection *connection, gdb_putback_char(connection, reply); LOG_DEBUG("Unexpected start of new packet"); break; + } else if (reply == 0x3) { + /* do not discard Ctrl-C */ + gdb_putback_char(connection, reply); + break; } LOG_WARNING("Discard unexpected char %c", reply); -- |
From: <ge...@op...> - 2025-05-18 15:52:00
|
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/+/8919 -- gerrit commit 0be891e86268900162b35eec92a16b5516865bac Author: Tim Newsome <ti...@si...> Date: Wed Sep 7 11:55:52 2022 -0700 rtos/hwthread: Hide unavailable targets from thread list. Imported from https://github.com/riscv-collab/riscv-openocd/pull/767 Change-Id: I53c6e2876d9bab70800a0f080e72a2abe0499120 Signed-off-by: Tim Newsome <ti...@si...> diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c index 76571c6b60..cc43a07b42 100644 --- a/src/rtos/hwthread.c +++ b/src/rtos/hwthread.c @@ -105,7 +105,8 @@ static int hwthread_update_threads(struct rtos *rtos) foreach_smp_target(head, target->smp_targets) { struct target *curr = head->target; - if (!target_was_examined(curr)) + if (!target_was_examined(curr) || + curr->state == TARGET_UNAVAILABLE) continue; ++thread_list_size; @@ -130,7 +131,8 @@ static int hwthread_update_threads(struct rtos *rtos) foreach_smp_target(head, target->smp_targets) { struct target *curr = head->target; - if (!target_was_examined(curr)) + if (!target_was_examined(curr) || + curr->state == TARGET_UNAVAILABLE) continue; threadid_t tid = threadid_from_target(curr); -- |
From: <ge...@op...> - 2025-05-18 09:52: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/+/8918 -- gerrit commit 7d8a6430ce8c8612bef49ae9c4d49be80fb8a963 Author: Tomas Vanek <va...@fb...> Date: Sun May 18 11:49:31 2025 +0200 flash, target: avoid logging of numeric target state Replace it by target_state_name() helper. Change-Id: I720f2bf121e6fd2c6987a7e8fa9e52593888ee6c Signed-off-by: Tomas Vanek <va...@fb...> diff --git a/src/flash/nor/ambiqmicro.c b/src/flash/nor/ambiqmicro.c index bb893778ce..67cc6b68a7 100644 --- a/src/flash/nor/ambiqmicro.c +++ b/src/flash/nor/ambiqmicro.c @@ -309,9 +309,9 @@ static int ambiqmicro_exec_command(struct target *target, */ target_poll(target); alive_sleep(100); - LOG_DEBUG("state = %d", target->state); } else { - LOG_ERROR("Target not halted or running %d", target->state); + LOG_ERROR("Target not halted or running (state is %s)", + target_state_name(target)); break; } } diff --git a/src/target/espressif/esp32.c b/src/target/espressif/esp32.c index 399ba8e7cd..5e2490a229 100644 --- a/src/target/espressif/esp32.c +++ b/src/target/espressif/esp32.c @@ -192,8 +192,8 @@ static int esp32_soc_reset(struct target *target) alive_sleep(10); xtensa_poll(target); if (timeval_ms() >= timeout) { - LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d", - target->state); + LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state %s", + target_state_name(target)); get_timeout = true; break; } diff --git a/src/target/espressif/esp32s2.c b/src/target/espressif/esp32s2.c index b86e43e626..e32893a6b2 100644 --- a/src/target/espressif/esp32s2.c +++ b/src/target/espressif/esp32s2.c @@ -272,8 +272,8 @@ static int esp32s2_soc_reset(struct target *target) alive_sleep(10); xtensa_poll(target); if (timeval_ms() >= timeout) { - LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state=%d", - target->state); + LOG_TARGET_ERROR(target, "Timed out waiting for CPU to be reset, target state %s", + target_state_name(target)); return ERROR_TARGET_TIMEOUT; } } diff --git a/src/target/espressif/esp32s3.c b/src/target/espressif/esp32s3.c index 82413f77fb..14f7a7bb64 100644 --- a/src/target/espressif/esp32s3.c +++ b/src/target/espressif/esp32s3.c @@ -193,8 +193,8 @@ static int esp32s3_soc_reset(struct target *target) xtensa_poll(target); if (timeval_ms() >= timeout) { LOG_TARGET_ERROR(target, - "Timed out waiting for CPU to be reset, target state=%d", - target->state); + "Timed out waiting for CPU to be reset, target state %s", + target_state_name(target)); get_timeout = true; break; } diff --git a/src/target/stm8.c b/src/target/stm8.c index 81c41f2b2a..7785d40ef0 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -870,7 +870,7 @@ static int stm8_poll(struct target *target) uint8_t csr1, csr2; #ifdef LOG_STM8 - LOG_DEBUG("target->state=%d", target->state); + LOG_DEBUG("target->state %s", target_state_name(target)); #endif /* read dm_csrx control regs */ diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c index 3a877edfa6..3366623d64 100644 --- a/src/target/xtensa/xtensa.c +++ b/src/target/xtensa/xtensa.c @@ -949,7 +949,8 @@ int xtensa_smpbreak_set(struct target *target, uint32_t set) xtensa->smp_break = set; if (target_was_examined(target)) res = xtensa_smpbreak_write(xtensa, xtensa->smp_break); - LOG_TARGET_DEBUG(target, "set smpbreak=%" PRIx32 ", state=%i", set, target->state); + LOG_TARGET_DEBUG(target, "set smpbreak=%" PRIx32 ", state %s", set, + target_state_name(target)); return res; } -- |
From: <ge...@op...> - 2025-05-18 09:14:46
|
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/+/8916 -- gerrit commit 715713450cdf7390412d02a655498289396a24c3 Author: Tim Newsome <ti...@si...> Date: Thu Nov 10 10:32:23 2022 -0800 gdb_server: Improve info message. Add target name and state to "Not running when halt was requested" message. Imported from https://github.com/riscv-collab/riscv-openocd/pull/763 Change-Id: Ic84e9a884b57caa270cfee0ca6fa6a0dd8e5d2bd Signed-off-by: Tim Newsome <ti...@si...> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index ef94b4cf0d..d596a76e01 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -3797,7 +3797,8 @@ static int gdb_input_inner(struct connection *connection) target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); gdb_con->ctrl_c = false; } else { - LOG_INFO("The target is not running when halt was requested, stopping GDB."); + LOG_TARGET_INFO(target, "Not running when halt was requested, stopping GDB. (state=%d)", + target->state); target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT); } } -- |