This is an automated email from Gerrit.

"Ahmed Haoues <ahmed.hao...@st.com>" just uploaded a new patch set to Gerrit, 
which you can find at https://review.openocd.org/c/openocd/+/8890

-- gerrit

commit 266d5d5f7f75604522f86043f60bb192835e7f42
Author: HAOUES Ahmed <ahmed.hao...@st.com>
Date:   Thu Jul 3 17:38:20 2025 +0100

    flash/stm32h7x: support STM32H7R/H7Sx
    
    The STM32H7R/H7Sx has a flash size up to 64 Kb
    Change-Id: I2e9d80758d1bc88defdd6bbd1787026373b39fa4
    Signed-off-by: HAOUES Ahmed <ahmed.hao...@st.com>

diff --git a/contrib/loaders/flash/stm32/stm32h7rx.S 
b/contrib/loaders/flash/stm32/stm32h7rx.S
new file mode 100644
index 0000000000..bfc4929d09
--- /dev/null
+++ b/contrib/loaders/flash/stm32/stm32h7rx.S
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/***************************************************************************
+ *   Copyright (C) 2017 by STMicroelectronics                              *
+ ***************************************************************************/
+
+       .text
+       .syntax unified
+       .cpu cortex-m4
+       .thumb
+
+/*
+ * Code limitations:
+ * The workarea must have size multiple of 4 bytes, since R/W
+ * operations are all at 32 bits.
+ * The workarea must be big enough to contain rp, wp and data, thus the minimum
+ * workarea size is: min_wa_size = sizeof(rp, wp, data) = 4 + 4 + sizeof(data).
+ *  - for 0x450 devices: sizeof(data) = 32 bytes, thus min_wa_size = 40 bytes.
+ *  - for 0x480 devices: sizeof(data) = 16 bytes, thus min_wa_size = 24 bytes.
+ * To benefit from concurrent host write-to-buffer and target
+ * write-to-flash, the workarea must be way bigger than the minimum.
+ *
+ * To avoid confusions the write word size is got from .block_size member of
+ * struct stm32h7x_part_info defined in stm32h7x.c
+*/
+
+/*
+ * Params :
+ * r0 = workarea start, status (out)
+ * r1 = workarea end
+ * r2 = target address
+ * r3 = count (of write words)
+ * r4 = size of write word
+ * r5 = flash reg base
+ *
+ * Clobbered:
+ * r6 - rp
+ * r7 - wp, status, tmp
+ * r8 - loop index, tmp
+ */
+
+#define STM32_FLASH_CR_OFFSET  0x10    /* offset of CR register in FLASH 
struct */
+#define STM32_FLASH_SR_OFFSET  0x14    /* offset of SR register in FLASH 
struct */
+#define STM32_FLASH_ICR_OFFSET 0x28    /* offset of SR register in FLASH 
struct */
+#define STM32_CR_PROG                  0x00000002      /* PG */
+#define STM32_SR_QW_MASK               0x00000004      /* QW */
+#define STM32_SR_ERROR_MASK            0x1F2E0000      /* DBECCERR | SNECCERR 
| RDSERR | RDPERR | OPERR
+                                                                               
           | INCERR | STRBERR | PGSERR | WRPERR */
+
+       .thumb_func
+       .global _start
+_start:
+       ldr             r6, [r0, #4]            /* read rp */
+
+wait_fifo:
+       ldr             r7, [r0, #0]            /* read wp */
+       cbz             r7, exit                        /* abort if wp == 0, 
status = 0 */
+       subs    r7, r7, r6                      /* number of bytes available 
for read in r7 */
+       ittt    mi                                      /* if wrapped around */
+       addmi   r7, r1                          /* add size of buffer */
+       submi   r7, r0
+       submi   r7, #8
+       cmp             r7, r4                          /* wait until data 
buffer is full */
+       bcc             wait_fifo
+
+       mov             r7, #STM32_CR_PROG
+       str             r7, [r5, #STM32_FLASH_CR_OFFSET]
+
+       mov             r8, #4
+       udiv    r8, r4, r8                      /* number of words is size of 
write word divided by 4*/
+write_flash:
+       dsb
+       ldr             r7, [r6], #0x04         /* read one word from src, 
increment ptr */
+       str             r7, [r2], #0x04         /* write one word to dst, 
increment ptr */
+       dsb
+       cmp             r6, r1                          /* if rp >= end of 
buffer ... */
+       it              cs
+       addcs   r6, r0, #8                      /* ... then wrap at buffer 
start */
+       subs    r8, r8, #1                      /* decrement loop index */
+       bne             write_flash                     /* loop if not done */
+
+busy:
+       ldr             r7, [r5, #STM32_FLASH_SR_OFFSET]
+       tst             r7, #STM32_SR_QW_MASK
+       bne             busy                            /* operation in 
progress, wait ... */
+
+       ldr             r7, [r5, #STM32_FLASH_ICR_OFFSET]
+       ldr             r8, =STM32_SR_ERROR_MASK
+       tst             r7, r8
+       bne             error                           /* fail... */
+
+       str             r6, [r0, #4]            /* store rp */
+       subs    r3, r3, #1                      /* decrement count */
+       bne             wait_fifo                       /* loop if not done */
+       b               exit
+
+error:
+       movs    r8, #0
+       str             r8, [r0, #4]            /* set rp = 0 on error */
+
+exit:
+       mov             r0, r7                          /* return status in r0 
*/
+       bkpt    #0x00
+
+       .pool
diff --git a/contrib/loaders/flash/stm32/stm32h7rx.inc 
b/contrib/loaders/flash/stm32/stm32h7rx.inc
new file mode 100644
index 0000000000..feecab6230
--- /dev/null
+++ b/contrib/loaders/flash/stm32/stm32h7rx.inc
@@ -0,0 +1,8 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0x46,0x68,0x07,0x68,0x77,0xb3,0xbf,0x1b,0x42,0xbf,0x7f,0x18,0x3f,0x1a,0x08,0x3f,
+0xa7,0x42,0xf6,0xd3,0x4f,0xf0,0x02,0x07,0x2f,0x61,0x4f,0xf0,0x04,0x08,0xb4,0xfb,
+0xf8,0xf8,0xbf,0xf3,0x4f,0x8f,0x56,0xf8,0x04,0x7b,0x42,0xf8,0x04,0x7b,0xbf,0xf3,
+0x4f,0x8f,0x8e,0x42,0x28,0xbf,0x00,0xf1,0x08,0x06,0xb8,0xf1,0x01,0x08,0xf0,0xd1,
+0x6f,0x69,0x17,0xf0,0x04,0x0f,0xfb,0xd1,0xaf,0x6a,0xdf,0xf8,0x1c,0x80,0x17,0xea,
+0x08,0x0f,0x03,0xd1,0x46,0x60,0x01,0x3b,0xd3,0xd1,0x03,0xe0,0x5f,0xf0,0x00,0x08,
+0xc0,0xf8,0x04,0x80,0x38,0x46,0x00,0xbe,0x00,0x00,0x2e,0x1f,
diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c
index 362b2c2d52..e1c86bd6ec 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -54,6 +54,18 @@ static const uint32_t 
stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
        [STM32_FLASH_WPSN_PRG_INDEX]    = 0x3C
 };
 
+static const uint32_t stm32h7rs_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
+       [STM32_FLASH_ACR_INDEX]                 = 0x00,
+       [STM32_FLASH_KEYR_INDEX]                = 0x04,
+       [STM32_FLASH_OPTKEYR_INDEX]             = 0x100,
+       [STM32_FLASH_SR_INDEX]                  = 0x14,
+       [STM32_FLASH_CR_INDEX]                  = 0x10,
+       [STM32_FLASH_ICR_INDEX]                 = 0x28,
+       [STM32_FLASH_OPTCR_INDEX]               = 0x104,
+       [STM32_FLASH_OPTSR_INDEX]               = 0x10C,
+       [STM32_FLASH_ISR_INDEX]                 = 0x24,
+};
+
 /* FLASH_CR register bits */
 #define FLASH_LOCK     (1 << 0)
 #define FLASH_PG       (1 << 1)
@@ -66,6 +78,19 @@ static const uint32_t 
stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
 #define FLASH_FW       (1 << 6)
 #define FLASH_START    (1 << 7)
 
+/* FLASH_ISR register bits for H7RS */
+#define FLASH_CRCRDERRF        (1 << 28) /* CRC read error flag */
+#define FLASH_CRCENDF  (1 << 27) /* CRC end flag */
+#define FLASH_DBECCERRF        (1 << 26) /* ECC double error flag */
+#define FLASH_SNECCERRF        (1 << 25) /* ECC single error flag */
+#define FLASH_RDSERRF  (1 << 24) /* Read security error flag */
+#define FLASH_INCERRF  (1 << 21) /* Inconsistency error flag */
+#define FLASH_OBLERRF  (1 << 20) /* Option byte loading error flag */
+#define FLASH_STRBERRF (1 << 19) /* Strobe error flag */
+#define FLASH_PGSERRF  (1 << 18) /* Programming sequence error flag */
+#define FLASH_WRPERRF  (1 << 17) /* Write protection error flag */
+#define FLASH_EOPF             (1 << 16) /* End-of-program flag */
+
 /* FLASH_SR register bits */
 #define FLASH_BSY      (1 << 0)  /* Operation in progress */
 #define FLASH_QW       (1 << 2)  /* Operation queue in progress */
@@ -81,6 +106,9 @@ static const uint32_t 
stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
 
 #define FLASH_ERROR (FLASH_WRPERR | FLASH_PGSERR | FLASH_STRBERR | 
FLASH_INCERR | FLASH_OPERR | \
                                         FLASH_RDPERR | FLASH_RDSERR | 
FLASH_SNECCERR | FLASH_DBECCERR)
+/* Possible errors for H7RS */
+#define FLASH_ERROR_H7RS (FLASH_CRCRDERRF | FLASH_CRCENDF | FLASH_DBECCERRF | 
FLASH_SNECCERRF| FLASH_RDSERRF | \
+                                        FLASH_INCERRF | FLASH_OBLERRF | 
FLASH_STRBERRF | FLASH_PGSERRF | FLASH_WRPERRF | FLASH_EOPF)
 
 /* FLASH_OPTCR register bits */
 #define OPT_LOCK       (1 << 0)
@@ -113,6 +141,7 @@ static const uint32_t 
stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
 #define DEVID_STM32H74_H75XX    0x450
 #define DEVID_STM32H7A_H7BXX    0x480
 #define DEVID_STM32H72_H73XX    0x483
+#define DEVID_STM32H7R_H7SXX   0x485
 
 struct stm32h7_rev {
        uint16_t rev;
@@ -167,12 +196,16 @@ static const struct stm32h7_rev stm32h72_h73xx_revs[] = {
        { 0x1000, "A" }, { 0x1001, "Z" },
 };
 
+static const struct stm32h7_rev stm32h7r_h7sxx_revs[] = {
+       { 0x1000, "A" }, { 0x2000, "B" },
+};
+
 static uint32_t stm32h74_h75xx_compute_flash_cr(uint32_t cmd, int snb)
 {
        return cmd | (snb << 8);
 }
 
-static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t cmd, int snb)
+static uint32_t stm32h7a_h7b_h7r_h7sxx_compute_flash_cr(uint32_t cmd, int snb)
 {
        /* save FW and START bits, to be right shifted by 2 bits later */
        const uint32_t tmp = cmd & (FLASH_FW | FLASH_START);
@@ -184,6 +217,7 @@ static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t 
cmd, int snb)
 }
 
 static inline int stm32h7_get_flash_status(struct flash_bank *bank, uint32_t 
*status);
+static inline int stm32h7rs_get_flash_status(struct flash_bank *bank, uint32_t 
*status);
 
 static const struct stm32h7_part_info stm32h7_parts[] = {
        {
@@ -215,7 +249,7 @@ static const struct stm32h7_part_info stm32h7_parts[] = {
        .fsize_addr                         = 0x08FFF80C,
        .wps_group_size             = 4,
        .wps_mask                           = 0xFFFFFFFF,
-       .compute_flash_cr           = stm32h7a_h7bxx_compute_flash_cr,
+       .compute_flash_cr           = stm32h7a_h7b_h7r_h7sxx_compute_flash_cr,
        .get_flash_error_status = stm32h7_get_flash_status,
        },
        {
@@ -234,6 +268,22 @@ static const struct stm32h7_part_info stm32h7_parts[] = {
        .compute_flash_cr       = stm32h74_h75xx_compute_flash_cr,
        .get_flash_error_status = stm32h7_get_flash_status,
        },
+       {
+       .id                                             = DEVID_STM32H7R_H7SXX,
+       .revs                                   = stm32h7r_h7sxx_revs,
+       .num_revs                               = 
ARRAY_SIZE(stm32h7r_h7sxx_revs),
+       .device_str                             = "STM32H7Rx/7Sx",
+       .page_size_kb                   = 8,
+       .block_size                             = 16,
+       .max_flash_size_kb              = 64,
+       .max_bank_size_kb               = 64,
+       .has_dual_bank                  = false,
+       .fsize_addr                             = 0x08FFF80C,
+       .wps_group_size                 = 1,
+       .wps_mask                               = 0xFF,
+       .compute_flash_cr               = 
stm32h7a_h7b_h7r_h7sxx_compute_flash_cr,
+       .get_flash_error_status = stm32h7rs_get_flash_status,
+       },
 };
 
 /* flash bank stm32x <base> <size> 0 0 <target#> */
@@ -301,10 +351,19 @@ static inline int stm32h7_get_flash_status(struct 
flash_bank *bank, uint32_t *st
        return stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, 
status);
 }
 
+static inline int stm32h7rs_get_flash_status(struct flash_bank *bank, uint32_t 
*status)
+{
+       return stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_ISR_INDEX, 
status);
+}
+
 static int stm32h7_wait_flash_op_queue(struct flash_bank *bank, int timeout)
 {
        uint32_t status;
        int retval;
+       struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
+       uint32_t device_id = stm32h7_info->idcode & 0xFFF;
+       int flash_clear_status_index;
+       uint32_t flash_error;
 
        /* wait for flash operations completion */
        for (;;) {
@@ -322,17 +381,26 @@ static int stm32h7_wait_flash_op_queue(struct flash_bank 
*bank, int timeout)
                alive_sleep(1);
        }
 
+       if (device_id == DEVID_STM32H7R_H7SXX) {
+                       flash_error = FLASH_ERROR_H7RS;
+                       flash_clear_status_index = STM32_FLASH_ICR_INDEX;
+
+       } else {
+                       flash_error = FLASH_ERROR;
+                       flash_clear_status_index = STM32_FLASH_CCR_INDEX;
+       }
+
        if (status & FLASH_WRPERR) {
-               LOG_ERROR("wait_flash_op_queue, WRPERR detected");
+               LOG_ERROR("wait_flash_op_queue, write protection error");
                retval = ERROR_FAIL;
        }
 
        /* Clear error + EOP flags but report errors */
-       if (status & FLASH_ERROR) {
+       if (status & flash_error) {
                if (retval == ERROR_OK)
                        retval = ERROR_FAIL;
                /* If this operation fails, we ignore it and report the 
original retval */
-               stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, 
status);
+               stm32h7_write_flash_reg_by_index(bank, 
flash_clear_status_index, status);
        }
        return retval;
 }
@@ -597,6 +665,9 @@ static int stm32h7_write_block(struct flash_bank *bank, 
const uint8_t *buffer,
 {
        struct target *target = bank->target;
        struct stm32h7_flash_bank *stm32h7_info = bank->driver_priv;
+       uint32_t device_id = stm32h7_info->idcode & 0XFFF;
+       int flash_clear_status_index;
+       uint32_t flash_error;
        /*
         * If the size of the data part of the buffer is not a multiple of 
.block_size, we get
         * "corrupted fifo read" pointer in target_run_flash_async_algorithm()
@@ -614,18 +685,38 @@ static int stm32h7_write_block(struct flash_bank *bank, 
const uint8_t *buffer,
 #include "../../../contrib/loaders/flash/stm32/stm32h7x.inc"
        };
 
-       if (target_alloc_working_area(target, sizeof(stm32h7_flash_write_code),
+       static const uint8_t stm32h7rs_flash_write_code[] = {
+#include "../../../contrib/loaders/flash/stm32/stm32h7rx.inc"
+       };
+
+       if (device_id == DEVID_STM32H7R_H7SXX) {
+               if (target_alloc_working_area(target, 
sizeof(stm32h7rs_flash_write_code),
                        &write_algorithm) != ERROR_OK) {
-               LOG_WARNING("no working area available, can't do block memory 
writes");
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-       }
+                       LOG_WARNING("no working area available, can't do block 
memory writes");
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+               }
 
-       retval = target_write_buffer(target, write_algorithm->address,
-                       sizeof(stm32h7_flash_write_code),
-                       stm32h7_flash_write_code);
-       if (retval != ERROR_OK) {
-               target_free_working_area(target, write_algorithm);
-               return retval;
+               retval = target_write_buffer(target, write_algorithm->address,
+                               sizeof(stm32h7rs_flash_write_code),
+                               stm32h7rs_flash_write_code);
+               if (retval != ERROR_OK) {
+                       target_free_working_area(target, write_algorithm);
+                       return retval;
+               }
+       } else {
+               if (target_alloc_working_area(target, 
sizeof(stm32h7_flash_write_code),
+                               &write_algorithm) != ERROR_OK) {
+                       LOG_WARNING("no working area available, can't do block 
memory writes");
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+               }
+
+               retval = target_write_buffer(target, write_algorithm->address,
+                               sizeof(stm32h7_flash_write_code),
+                               stm32h7_flash_write_code);
+               if (retval != ERROR_OK) {
+                       target_free_working_area(target, write_algorithm);
+                       return retval;
+               }
        }
 
        /* memory buffer */
@@ -676,13 +767,22 @@ static int stm32h7_write_block(struct flash_bank *bank, 
const uint8_t *buffer,
 
                uint32_t flash_sr = buf_get_u32(reg_params[0].value, 0, 32);
 
+               if (device_id == DEVID_STM32H7R_H7SXX) {
+                       flash_error = FLASH_ERROR_H7RS;
+                       flash_clear_status_index = STM32_FLASH_ICR_INDEX;
+
+               } else {
+                       flash_error = FLASH_ERROR;
+                       flash_clear_status_index = STM32_FLASH_CCR_INDEX;
+               }
+
                if (flash_sr & FLASH_WRPERR)
                        LOG_ERROR("flash memory write protected");
 
-               if ((flash_sr & FLASH_ERROR) != 0) {
-                       LOG_ERROR("flash write failed, FLASH_SR = 0x%08" 
PRIx32, flash_sr);
+               if ((flash_sr & flash_error) != 0) {
+                       LOG_ERROR("flash write failed, status = 0x%08" PRIx32, 
flash_sr);
                        /* Clear error + EOP flags but report errors */
-                       stm32h7_write_flash_reg_by_index(bank, 
STM32_FLASH_CCR_INDEX, flash_sr);
+                       stm32h7_write_flash_reg_by_index(bank, 
flash_clear_status_index, flash_sr);
                        retval = ERROR_FAIL;
                }
        }
@@ -809,8 +909,11 @@ static int stm32h7_probe(struct flash_bank *bank)
        LOG_DEBUG("device id = 0x%08" PRIx32, stm32h7_info->idcode);
 
        device_id = stm32h7_info->idcode & 0xfff;
-
-       stm32h7_info->flash_regs = stm32h7_flash_regs;
+       if (device_id == DEVID_STM32H7R_H7SXX) {
+               stm32h7_info->flash_regs = stm32h7rs_flash_regs;
+       } else {
+               stm32h7_info->flash_regs = stm32h7_flash_regs;
+       }
 
        for (unsigned int n = 0; n < ARRAY_SIZE(stm32h7_parts); n++) {
                if (device_id == stm32h7_parts[n].id)
@@ -871,6 +974,7 @@ static int stm32h7_probe(struct flash_bank *bank)
                        flash_size_in_kb /= 2;
                break;
        case DEVID_STM32H72_H73XX:
+       case DEVID_STM32H7R_H7SXX:
                break;
        default:
                LOG_ERROR("unsupported device");
diff --git a/tcl/target/stm32h7rx.cfg b/tcl/target/stm32h7rx.cfg
new file mode 100644
index 0000000000..d584723f36
--- /dev/null
+++ b/tcl/target/stm32h7rx.cfg
@@ -0,0 +1,140 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# script for stm32h7x family
+
+#
+# stm32h7 devices support both JTAG and SWD transports.
+#
+source [find target/swj-dp.tcl]
+source [find mem_helper.tcl]
+
+if { [info exists CHIPNAME] } {
+   set _CHIPNAME $CHIPNAME
+} else {
+   set _CHIPNAME stm32h7x
+}
+
+# Issue a warning when hla is used, and fallback to single core configuration
+if { [using_hla] } {
+       echo "Error : hla does not support multicore debugging"
+}
+
+set _ENDIAN little
+
+# Work-area is a space in RAM used for flash programming
+# By default use 64kB
+if { [info exists WORKAREASIZE] } {
+   set _WORKAREASIZE $WORKAREASIZE
+} else {
+   set _WORKAREASIZE 0x10000
+}
+
+#jtag scan chain
+if { [info exists CPUTAPID] } {
+   set _CPUTAPID $CPUTAPID
+} else {
+   if { [using_jtag] } {
+         set _CPUTAPID 0x6ba00477
+   } {
+      set _CPUTAPID 0x6ba02477
+   }
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 
$_CPUTAPID
+dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
+
+if {[using_jtag]} {
+   jtag newtap $_CHIPNAME bs -irlen 5
+}
+
+target create $_CHIPNAME.ap0 mem_ap -dap $_CHIPNAME.dap -ap-num 0
+target create $_CHIPNAME.cpu0 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap 
-ap-num 1
+# test ram area
+$_CHIPNAME.cpu0 configure -work-area-phys 0x24000000 -work-area-size 
$_WORKAREASIZE -work-area-backup 0
+
+flash bank $_CHIPNAME.flash stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu0
+
+# Make sure that cpu0 is selected
+targets $_CHIPNAME.cpu0
+
+# Clock after reset is HSI at 64 MHz, no need of PLL
+adapter speed 1800
+
+adapter srst delay 100
+if {[using_jtag]} {
+ jtag_ntrst_delay 100
+}
+
+# use hardware reset
+#
+# The STM32H7 does not support connect_assert_srst mode because the AXI is
+# unavailable while SRST is asserted, and that is used to access the DBGMCU
+# component at 0x5C001000 in the examine-end event handler.
+#
+# It is possible to access the DBGMCU component at 0xE00E1000 via AP2 instead
+# of the default AP0, and that works with SRST asserted; however, nonzero AP
+# usage does not work with HLA, so is not done by default. That change could be
+# made in a local configuration file if connect_assert_srst mode is needed for
+# a specific application and a non-HLA adapter is in use.
+reset_config srst_nogate
+
+if {![using_hla]} {
+   # if srst is not fitted use SYSRESETREQ to
+   # perform a soft reset
+       $_CHIPNAME.cpu0 cortex_m reset_config sysresetreq
+
+   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB 
signal
+   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3
+   # makes the data access cacheable. This allows reading and writing data in 
the
+   # CPU cache from the debugger, which is far more useful than going straight 
to
+   # RAM when operating on typical variables, and is generally no worse when
+   # operating on special memory locations.
+   $_CHIPNAME.dap apcsw 0x08000000 0x08000000
+}
+
+$_CHIPNAME.cpu0 configure -event examine-end {
+       # Enable debug during low power modes (uses more power)
+       # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP
+       stm32h7x_dbgmcu_mmw 0x004 0x00000007 0
+
+       # Enable clock for tracing
+       # DBGMCU_CR |= TRACECLKEN
+       stm32h7x_dbgmcu_mmw 0x004 0x00100000 0
+}
+
+$_CHIPNAME.cpu0 configure -event reset-init {
+       # Clock after reset is HSI at 64 MHz, no need of PLL
+       adapter speed 4000
+}
+
+# get _CHIPNAME from current target
+proc stm32h7x_get_chipname {} {
+       set t [target current]
+       set sep [string last "." $t]
+       if {$sep == -1} {
+               return $t
+       }
+       return [string range $t 0 [expr {$sep - 1}]]
+}
+
+# like mrw, but with target selection
+proc stm32h7x_mrw {used_target reg} {
+       return [$used_target read_memory $reg 32 1]
+}
+
+# like mmw, but with target selection
+proc stm32h7x_mmw {used_target reg setbits clearbits} {
+       set old [stm32h7x_mrw $used_target $reg]
+       set new [expr {($old & ~$clearbits) | $setbits}]
+       $used_target mww $reg $new
+}
+
+# mmw for dbgmcu component registers, it accepts the register offset from 
dbgmcu base
+# this procedure will use the mem_ap on AP2 whenever possible
+proc stm32h7x_dbgmcu_mmw {reg_offset setbits clearbits} {
+       set _CHIPNAME [stm32h7x_get_chipname]
+       set used_target [target current]
+       set reg_addr [expr {0x5C001000 + $reg_offset}]
+
+       stm32h7x_mmw $used_target $reg_addr $setbits $clearbits
+}

-- 

Reply via email to