This is an automated email from Gerrit.

"Fedi Bouzazi <fedi.bouz...@st.com>" just uploaded a new patch set to Gerrit, 
which you can find at https://review.openocd.org/c/openocd/+/8086

-- gerrit

commit c24ef2caca0a4285dc80eb8aee9196f99f5f177c
Author: fedi BOUZAZI <fedi.bouz...@st.com>
Date:   Mon Aug 15 14:18:00 2022 +0100

    flash/stm32h7x: support STM32H7R/H7Sx
    
    Change-Id: I7893cd08bdfa02368fe9ac18146c94825721f071
    Signed-off-by: fedi BOUZAZI <fedi.bouz...@st.com>
    Reviewed-on: https://gerrit.st.com/c/stm32ide/official/openocd/+/347108
    Reviewed-by: Tarek BOCHKATI <tarek.bouchk...@st.com>
    Tested-by: CITOOLS <mdg-smet-aci-revi...@list.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 c02fae992c..3ba57c873a 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -13,26 +13,52 @@
 #include <target/cortex_m.h>
 
 
-/* Erase time can be as high as 1000ms, 10x this and it's toast... */
-#define FLASH_ERASE_TIMEOUT 10000
-#define FLASH_WRITE_TIMEOUT 5
 
-/* RM 433 */
-/* Same Flash registers for both banks, */
-/* access depends on Flash Base address */
-#define FLASH_ACR       0x00
-#define FLASH_KEYR      0x04
-#define FLASH_OPTKEYR   0x08
-#define FLASH_CR        0x0C
-#define FLASH_SR        0x10
-#define FLASH_CCR       0x14
-#define FLASH_OPTCR     0x18
-#define FLASH_OPTSR_CUR 0x1C
-#define FLASH_OPTSR_PRG 0x20
-#define FLASH_OPTCCR    0x24
-#define FLASH_WPSN_CUR  0x38
-#define FLASH_WPSN_PRG  0x3C
+enum stm32h7_flash_reg_index {
+       STM32_FLASH_ACR_INDEX,
+       STM32_FLASH_KEYR_INDEX,
+       STM32_FLASH_OPTKEYR_INDEX,
+       STM32_FLASH_SR_INDEX,
+       STM32_FLASH_CR_INDEX,
+       STM32_FLASH_ICR_INDEX,
+       STM32_FLASH_CCR_INDEX,
+       STM32_FLASH_OPTCR_INDEX,
+       STM32_FLASH_OPTSR_INDEX,
+       STM32_FLASH_OPTSR_CUR_INDEX,
+       STM32_FLASH_OPTSR_PRG_INDEX,
+       STM32_FLASH_OPTCCR_INDEX,
+       STM32_FLASH_WPSN_CUR_INDEX,
+       STM32_FLASH_WPSN_PRG_INDEX,
+       STM32_FLASH_ISR_INDEX,
+       STM32_FLASH_REG_INDEX_NUM,
+};
+
+static const uint32_t stm32h7_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
+       [STM32_FLASH_ACR_INDEX]                 = 0x00,
+       [STM32_FLASH_KEYR_INDEX]                = 0x04,
+       [STM32_FLASH_OPTKEYR_INDEX]             = 0x08,
+       [STM32_FLASH_SR_INDEX]                  = 0x10,
+       [STM32_FLASH_CR_INDEX]                  = 0x0C,
+       [STM32_FLASH_CCR_INDEX]                 = 0x14,
+       [STM32_FLASH_OPTCR_INDEX]               = 0x18,
+       [STM32_FLASH_OPTSR_CUR_INDEX]   = 0x1C,
+       [STM32_FLASH_OPTSR_PRG_INDEX]   = 0x20,
+       [STM32_FLASH_OPTCCR_INDEX]              = 0x24,
+       [STM32_FLASH_WPSN_CUR_INDEX]    = 0x38,
+       [STM32_FLASH_WPSN_PRG_INDEX]    = 0x3C
+};
 
+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)
@@ -46,6 +72,61 @@
 #define FLASH_FW       (1 << 6)
 #define FLASH_START    (1 << 7)
 
+/* FLASH_CR register bits for H7RS (only new positions and new bits) */
+#define H7RS_FLASH_START    (1 << 5)
+#define H7RS_FLASH_FW       (1 << 4)
+#define H7RS_ALL_BANKS         (1 << 24)
+
+
+/* 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_WRPERR   (1 << 17) /* Write protection error flag */
+#define FLASH_EOPF             (1 << 16) /* End-of-program flag */
+
+/* Erase time can be as high as 1000ms, 10x this and it's toast... */
+#define FLASH_ERASE_TIMEOUT 10000
+#define FLASH_WRITE_TIMEOUT 5
+#define MASS_ERASE_TIMEOUT 30000
+/* RM 433 */
+/* Same Flash registers for both banks, */
+/* access depends on Flash Base address */
+/*#define FLASH_ACR       0x00
+#define FLASH_KEYR      0x04
+#define FLASH_OPTKEYR   0x100
+#define FLASH_CR        0x10
+#define FLASH_SR        0x14
+#define FLASH_ICR       0x28
+#define FLASH_CCR       0x30
+#define FLASH_OPTCR     0x18
+#define FLASH_OPTSR_CUR 0x1C
+#define FLASH_OPTSR_PRG 0x20
+#define FLASH_OPTCCR    0x24
+#define FLASH_WPSN_CUR  0x38
+#define FLASH_WPSN_PRG  0x3C
+#define FLASH_ISR              0x24*/
+
+
+/* FLASH_ISR register bits */
+#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 */
@@ -59,8 +140,13 @@
 #define FLASH_SNECCERR (1 << 25) /* Single ECC error */
 #define FLASH_DBECCERR (1 << 26) /* Double ECC error */
 
-#define FLASH_ERROR (FLASH_WRPERR | FLASH_PGSERR | FLASH_STRBERR | 
FLASH_INCERR | FLASH_OPERR | \
-                                        FLASH_RDPERR | FLASH_RDSERR | 
FLASH_SNECCERR | FLASH_DBECCERR)
+#define FLASH_ERROR (FLASH_DBECCERR | FLASH_SNECCERR | FLASH_RDSERR | 
FLASH_RDPERR | FLASH_OPERR | \
+                                        FLASH_INCERR | FLASH_STRBERR | 
FLASH_PGSERR | FLASH_WRPERR | FLASH_QW | FLASH_BSY)
+
+/* 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)
@@ -93,6 +179,7 @@
 #define DEVID_STM32H74_H75XX    0x450
 #define DEVID_STM32H7A_H7BXX    0x480
 #define DEVID_STM32H72_H73XX    0x483
+#define DEVID_STM32H7R_H7SXX   0x485
 
 struct stm32h7x_rev {
        uint16_t rev;
@@ -117,13 +204,16 @@ struct stm32h7x_part_info {
        uint32_t wps_mask;
        /* function to compute flash_cr register values */
        uint32_t (*compute_flash_cr)(uint32_t cmd, int snb);
+       int (*get_flash_error_status)(struct flash_bank *bank, uint32_t 
*status);
 };
 
 struct stm32h7x_flash_bank {
        bool probed;
        uint32_t idcode;
        uint32_t user_bank_size;
-       uint32_t flash_regs_base;    /* Address of flash reg controller */
+       uint32_t flash_regs_base;   /* Address of flash reg controller */
+       uint32_t err_stat_mask;
+       const uint32_t *flash_regs;
        const struct stm32h7x_part_info *part_info;
 };
 
@@ -145,6 +235,10 @@ static const struct stm32h7x_rev stm32h72_h73xx_revs[] = {
        { 0x1000, "A" }, { 0x1001, "Z" },
 };
 
+static const struct stm32h7x_rev stm32h7r_h7sxx_revs[] = {
+       { 0x1000, "A" },
+};
+
 static uint32_t stm32h74_h75xx_compute_flash_cr(uint32_t cmd, int snb)
 {
        return cmd | (snb << 8);
@@ -161,51 +255,78 @@ static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t 
cmd, int snb)
        return cmd | (tmp >> 2) | (snb << 6);
 }
 
+static uint32_t stm32h7r_h7sxx__compute_flash_cr(uint32_t cmd, int snb)
+{
+               return cmd | (snb << 6);
+}
+
+static inline int stm32h7x_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 stm32h7x_part_info stm32h7x_parts[] = {
        {
-       .id                                     = DEVID_STM32H74_H75XX,
-       .revs                           = stm32h74_h75xx_revs,
-       .num_revs                       = ARRAY_SIZE(stm32h74_h75xx_revs),
-       .device_str                     = "STM32H74x/75x",
-       .page_size_kb           = 128,
-       .block_size                     = 32,
-       .max_flash_size_kb      = 2048,
-       .max_bank_size_kb       = 1024,
-       .has_dual_bank          = true,
-       .fsize_addr                     = 0x1FF1E880,
-       .wps_group_size         = 1,
-       .wps_mask                       = 0xFF,
-       .compute_flash_cr       = stm32h74_h75xx_compute_flash_cr,
+       .id                                             = DEVID_STM32H74_H75XX,
+       .revs                                   = stm32h74_h75xx_revs,
+       .num_revs                               = 
ARRAY_SIZE(stm32h7r_h7sxx_revs),
+       .device_str                             = "STM32H74x/75x",
+       .page_size_kb                   = 128,
+       .block_size                             = 32,
+       .max_flash_size_kb              = 2048,
+       .max_bank_size_kb               = 1024,
+       .has_dual_bank                  = true,
+       .fsize_addr                             = 0x1FF1E880,
+       .wps_group_size                 = 1,
+       .wps_mask                               = 0xFF,
+       .compute_flash_cr               = stm32h74_h75xx_compute_flash_cr,
+       .get_flash_error_status = stm32h7x_get_flash_status,
+       },
+       {
+       .id                                             = DEVID_STM32H7A_H7BXX,
+       .revs                                   = stm32h7a_h7bxx_revs,
+       .num_revs                               = 
ARRAY_SIZE(stm32h7a_h7bxx_revs),
+       .device_str                             = "STM32H7Ax/7Bx",
+       .page_size_kb                   = 8,
+       .block_size                             = 16,
+       .max_flash_size_kb              = 2048,
+       .max_bank_size_kb               = 1024,
+       .has_dual_bank                  = true,
+       .fsize_addr                             = 0x08FFF80C,
+       .wps_group_size                 = 4,
+       .wps_mask                               = 0xFFFFFFFF,
+       .compute_flash_cr               = stm32h7a_h7bxx_compute_flash_cr,
+       .get_flash_error_status = stm32h7x_get_flash_status,
        },
        {
-       .id                                     = DEVID_STM32H7A_H7BXX,
-       .revs                           = stm32h7a_h7bxx_revs,
-       .num_revs                       = ARRAY_SIZE(stm32h7a_h7bxx_revs),
-       .device_str                     = "STM32H7Ax/7Bx",
-       .page_size_kb           = 8,
-       .block_size                     = 16,
-       .max_flash_size_kb      = 2048,
-       .max_bank_size_kb       = 1024,
-       .has_dual_bank          = true,
-       .fsize_addr                     = 0x08FFF80C,
-       .wps_group_size         = 4,
-       .wps_mask                       = 0xFFFFFFFF,
-       .compute_flash_cr       = stm32h7a_h7bxx_compute_flash_cr,
+       .id                                             = DEVID_STM32H72_H73XX,
+       .revs                                   = stm32h72_h73xx_revs,
+       .num_revs                               = 
ARRAY_SIZE(stm32h72_h73xx_revs),
+       .device_str                             = "STM32H72x/73x",
+       .page_size_kb                   = 128,
+       .block_size                             = 32,
+       .max_flash_size_kb              = 1024,
+       .max_bank_size_kb               = 1024,
+       .has_dual_bank                  = false,
+       .fsize_addr                             = 0x1FF1E880,
+       .wps_group_size                 = 1,
+       .wps_mask                               = 0xFF,
+       .compute_flash_cr               = stm32h74_h75xx_compute_flash_cr,
+       .get_flash_error_status = stm32h7x_get_flash_status,
        },
        {
-       .id                                     = DEVID_STM32H72_H73XX,
-       .revs                           = stm32h72_h73xx_revs,
-       .num_revs                       = ARRAY_SIZE(stm32h72_h73xx_revs),
-       .device_str                     = "STM32H72x/73x",
-       .page_size_kb           = 128,
-       .block_size                     = 32,
-       .max_flash_size_kb      = 1024,
-       .max_bank_size_kb       = 1024,
-       .has_dual_bank          = false,
-       .fsize_addr                     = 0x1FF1E880,
-       .wps_group_size         = 1,
-       .wps_mask                       = 0xFF,
-       .compute_flash_cr   = stm32h74_h75xx_compute_flash_cr,
+       .id                                             = DEVID_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               = stm32h7r_h7sxx__compute_flash_cr,
+       .get_flash_error_status = stm32h7rs_get_flash_status,
        },
 };
 
@@ -214,7 +335,6 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
 FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)
 {
        struct stm32h7x_flash_bank *stm32x_info;
-
        if (CMD_ARGC < 6)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
@@ -244,6 +364,13 @@ static inline int stm32x_read_flash_reg(struct flash_bank 
*bank, uint32_t reg_of
        return retval;
 }
 
+static inline int stm32h7_read_flash_reg_by_index(struct flash_bank *bank,
+       enum stm32h7_flash_reg_index reg_index, uint32_t *value)
+{
+       struct stm32h7x_flash_bank *stm32h7_info = bank->driver_priv;
+       return stm32x_read_flash_reg(bank, stm32h7_info->flash_regs[reg_index], 
value);
+}
+
 static inline int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t 
reg_offset, uint32_t value)
 {
        uint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset);
@@ -254,20 +381,37 @@ static inline int stm32x_write_flash_reg(struct 
flash_bank *bank, uint32_t reg_o
 
        return retval;
 }
+static inline int stm32h7_write_flash_reg_by_index(struct flash_bank *bank,
+       enum stm32h7_flash_reg_index reg_index, uint32_t value)
+{
+       struct stm32h7x_flash_bank *stm32h7_info = bank->driver_priv;
+       return stm32x_write_flash_reg(bank, 
stm32h7_info->flash_regs[reg_index], value);
+}
+static inline int stm32h7x_get_flash_status(struct flash_bank *bank, uint32_t 
*status)
+{
+       return stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, 
status);
+}
 
-static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t 
*status)
+static inline int stm32h7rs_get_flash_status(struct flash_bank *bank, uint32_t 
*status)
 {
-       return stm32x_read_flash_reg(bank, FLASH_SR, status);
+       return stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_ISR_INDEX, 
status);
 }
 
+/*static inline int stm32x_get_flash_error_status(struct flash_bank *bank, 
uint32_t *status)
+{
+       return stm32x_read_flash_reg(bank, INDE, status);
+}*/
+
 static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout)
 {
        uint32_t status;
        int retval;
+       struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
+       uint32_t device_id = stm32x_info->idcode & 0xFFF;
 
        /* wait for flash operations completion */
        for (;;) {
-               retval = stm32x_get_flash_status(bank, &status);
+               retval = stm32h7x_get_flash_status(bank, &status);
                if (retval != ERROR_OK)
                        return retval;
 
@@ -281,6 +425,21 @@ static int stm32x_wait_flash_op_queue(struct flash_bank 
*bank, int timeout)
                alive_sleep(1);
        }
 
+       if (device_id == DEVID_STM32H7R_H7SXX) {
+               if (status & FLASH_WRPERRF) {
+                       LOG_ERROR("wait_flash_op_queue, WRPERRF detected");
+                       retval = ERROR_FAIL;
+               }
+               /* Clear error + EOP flags but report errors */
+                       if (status & FLASH_ERROR_H7RS) {
+                               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_ICR_INDEX, status);
+                       }
+                       return retval;
+       }
+
        if (status & FLASH_WRPERR) {
                LOG_ERROR("wait_flash_op_queue, WRPERR detected");
                retval = ERROR_FAIL;
@@ -291,7 +450,7 @@ static int stm32x_wait_flash_op_queue(struct flash_bank 
*bank, int timeout)
                if (retval == ERROR_OK)
                        retval = ERROR_FAIL;
                /* If this operation fails, we ignore it and report the 
original retval */
-               stm32x_write_flash_reg(bank, FLASH_CCR, status);
+               stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CCR_INDEX, 
status);
        }
        return retval;
 }
@@ -303,7 +462,7 @@ static int stm32x_unlock_reg(struct flash_bank *bank)
        /* first check if not already unlocked
         * otherwise writing on FLASH_KEYR will fail
         */
-       int retval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl);
+       int retval = stm32h7_read_flash_reg_by_index(bank, 
STM32_FLASH_CR_INDEX, &ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -311,15 +470,15 @@ static int stm32x_unlock_reg(struct flash_bank *bank)
                return ERROR_OK;
 
        /* unlock flash registers for bank */
-       retval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY1);
+       retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, 
KEY1);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY2);
+       retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, 
KEY2);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl);
+       retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 
&ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -334,7 +493,7 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank)
 {
        uint32_t ctrl;
 
-       int retval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl);
+       int retval = stm32h7_read_flash_reg_by_index(bank, 
STM32_FLASH_OPTCR_INDEX, &ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -342,15 +501,15 @@ static int stm32x_unlock_option_reg(struct flash_bank 
*bank)
                return ERROR_OK;
 
        /* unlock option registers */
-       retval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY1);
+       retval = stm32h7_write_flash_reg_by_index(bank, 
STM32_FLASH_OPTKEYR_INDEX, OPTKEY1);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY2);
+       retval = stm32h7_write_flash_reg_by_index(bank, 
STM32_FLASH_OPTKEYR_INDEX, OPTKEY2);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl);
+       retval = stm32h7_read_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, 
&ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -364,12 +523,12 @@ static int stm32x_unlock_option_reg(struct flash_bank 
*bank)
 
 static inline int stm32x_lock_reg(struct flash_bank *bank)
 {
-       return stm32x_write_flash_reg(bank, FLASH_CR, FLASH_LOCK);
+       return stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 
FLASH_LOCK);
 }
 
 static inline int stm32x_lock_option_reg(struct flash_bank *bank)
 {
-       return stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_LOCK);
+       return stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_OPTCR_INDEX, 
OPT_LOCK);
 }
 
 static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, 
uint32_t value)
@@ -382,25 +541,26 @@ static int stm32x_write_option(struct flash_bank *bank, 
uint32_t reg_offset, uin
                goto flash_options_lock;
 
        /* write option bytes */
-       retval = stm32x_write_flash_reg(bank, reg_offset, value);
+       retval = stm32h7_write_flash_reg_by_index(bank, reg_offset, value);
        if (retval != ERROR_OK)
                goto flash_options_lock;
 
-       /* Remove OPT error flag before programming */
-       retval = stm32x_write_flash_reg(bank, FLASH_OPTCCR, 
OPT_CLR_OPTCHANGEERR);
+       /* Remove OPT error flag before programming  */
+       retval = stm32h7_write_flash_reg_by_index(bank, 
STM32_FLASH_OPTCCR_INDEX, OPT_CLR_OPTCHANGEERR);
        if (retval != ERROR_OK)
                goto flash_options_lock;
 
        /* start programming cycle */
-       retval = stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_START);
+       retval = stm32h7_write_flash_reg_by_index(bank, 
STM32_FLASH_OPTCR_INDEX, OPT_START);
        if (retval != ERROR_OK)
                goto flash_options_lock;
 
        /* wait for completion */
        int timeout = FLASH_ERASE_TIMEOUT;
+
        uint32_t status;
        for (;;) {
-               retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_CUR, &status);
+               retval = stm32h7_read_flash_reg_by_index(bank, 
STM32_FLASH_OPTSR_CUR_INDEX, &status);
                if (retval != ERROR_OK) {
                        LOG_ERROR("stm32x_options_program: failed to read 
FLASH_OPTSR_CUR");
                        goto flash_options_lock;
@@ -434,7 +594,7 @@ static int stm32x_modify_option(struct flash_bank *bank, 
uint32_t reg_offset, ui
 {
        uint32_t data;
 
-       int retval = stm32x_read_flash_reg(bank, reg_offset, &data);
+       int retval = stm32h7_read_flash_reg_by_index(bank, reg_offset, &data);
        if (retval != ERROR_OK)
                return retval;
 
@@ -448,7 +608,7 @@ static int stm32x_protect_check(struct flash_bank *bank)
        uint32_t protection;
 
        /* read 'write protection' settings */
-       int retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection);
+       int retval = stm32h7_read_flash_reg_by_index(bank, 
STM32_FLASH_WPSN_CUR_INDEX, &protection);
        if (retval != ERROR_OK) {
                LOG_DEBUG("unable to read WPSN_CUR register");
                return retval;
@@ -465,6 +625,7 @@ static int stm32x_erase(struct flash_bank *bank, unsigned 
int first,
 {
        struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
        int retval, retval2;
+       uint32_t device_id = stm32x_info->idcode & 0xFFF;
 
        assert(first < bank->num_sectors);
        assert(last < bank->num_sectors);
@@ -486,16 +647,27 @@ static int stm32x_erase(struct flash_bank *bank, unsigned 
int first,
        3. Set the STRT bit in the FLASH_CR register
        4. Wait for flash operations completion
         */
+       uint32_t erase_flags_1;
+       uint32_t erase_flags_2;
+
+       if (device_id == DEVID_STM32H7R_H7SXX) {
+               erase_flags_1 = FLASH_SER;
+               erase_flags_2 = FLASH_SER | H7RS_FLASH_START;
+       } else {
+               erase_flags_1 = FLASH_SER | FLASH_PSIZE_64;
+               erase_flags_2 = FLASH_SER | FLASH_PSIZE_64 | FLASH_START;
+       }
+
        for (unsigned int i = first; i <= last; i++) {
                LOG_DEBUG("erase sector %u", i);
-               retval = stm32x_write_flash_reg(bank, FLASH_CR,
-                               
stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64, i));
+               retval = stm32h7_write_flash_reg_by_index(bank, 
STM32_FLASH_CR_INDEX,
+                                               
stm32x_info->part_info->compute_flash_cr(erase_flags_1, i));
                if (retval != ERROR_OK) {
                        LOG_ERROR("Error erase sector %u", i);
                        goto flash_lock;
                }
-               retval = stm32x_write_flash_reg(bank, FLASH_CR,
-                               
stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64 | 
FLASH_START, i));
+               retval = stm32h7_write_flash_reg_by_index(bank, 
STM32_FLASH_CR_INDEX,
+                               
stm32x_info->part_info->compute_flash_cr(erase_flags_2, i));
                if (retval != ERROR_OK) {
                        LOG_ERROR("Error erase sector %u", i);
                        goto flash_lock;
@@ -507,7 +679,6 @@ static int stm32x_erase(struct flash_bank *bank, unsigned 
int first,
                        goto flash_lock;
                }
        }
-
 flash_lock:
        retval2 = stm32x_lock_reg(bank);
        if (retval2 != ERROR_OK)
@@ -529,7 +700,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, 
unsigned int first,
        }
 
        /* read 'write protection' settings */
-       int retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection);
+       int retval = stm32h7_read_flash_reg_by_index(bank, 
STM32_FLASH_WPSN_CUR_INDEX, &protection);
        if (retval != ERROR_OK) {
                LOG_DEBUG("unable to read WPSN_CUR register");
                return retval;
@@ -548,7 +719,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, 
unsigned int first,
        LOG_DEBUG("stm32x_protect, option_bytes written WPSN 0x%" PRIx32, 
protection);
 
        /* apply new option value */
-       return stm32x_write_option(bank, FLASH_WPSN_PRG, protection);
+       return stm32x_write_option(bank, STM32_FLASH_WPSN_PRG_INDEX, 
protection);
 }
 
 static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
@@ -556,6 +727,9 @@ static int stm32x_write_block(struct flash_bank *bank, 
const uint8_t *buffer,
 {
        struct target *target = bank->target;
        struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
+       uint32_t device_id = stm32x_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()
@@ -563,28 +737,51 @@ static int stm32x_write_block(struct flash_bank *bank, 
const uint8_t *buffer,
        uint32_t data_size = 512 * stm32x_info->part_info->block_size;
        uint32_t buffer_size = 8 + data_size;
        struct working_area *write_algorithm;
+
+
+
        struct working_area *source;
        uint32_t address = bank->base + offset;
        struct reg_param reg_params[6];
        struct armv7m_algorithm armv7m_info;
        int retval = ERROR_OK;
 
-       static const uint8_t stm32x_flash_write_code[] = {
+       static const uint8_t stm32x_flash_write_code_h7x[] = {
 #include "../../../contrib/loaders/flash/stm32/stm32h7x.inc"
        };
 
-       if (target_alloc_working_area(target, sizeof(stm32x_flash_write_code),
+       static const uint8_t stm32x_flash_write_code_h7rs[] = {
+#include "../../../contrib/loaders/flash/stm32/stm32h7rx.inc"
+       };
+
+       if (device_id == DEVID_STM32H7R_H7SXX) {
+               if (target_alloc_working_area(target, 
sizeof(stm32x_flash_write_code_h7rs),
                        &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(stm32x_flash_write_code),
-                       stm32x_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(stm32x_flash_write_code_h7rs),
+                               stm32x_flash_write_code_h7rs);
+               if (retval != ERROR_OK) {
+                       target_free_working_area(target, write_algorithm);
+                       return retval;
+               }
+       } else {
+               if (target_alloc_working_area(target, 
sizeof(stm32x_flash_write_code_h7x),
+                       &write_algorithm) != ERROR_OK) {
+                       LOG_WARNING("no working area available, can't do block 
memory writes");
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+               }
+
+               retval = target_write_buffer(target, write_algorithm->address,
+                               sizeof(stm32x_flash_write_code_h7x),
+                               stm32x_flash_write_code_h7x);
+               if (retval != ERROR_OK) {
+                       target_free_working_area(target, write_algorithm);
+                       return retval;
+               }
        }
 
        /* memory buffer */
@@ -635,13 +832,22 @@ static int stm32x_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_CCR_INDEX;
+
+               } else {
+                       flash_error = FLASH_ERROR;
+                       flash_clear_status_index = STM32_FLASH_ICR_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, FLASH_ISR = 0x%08" 
PRIx32, flash_sr);
                        /* Clear error + EOP flags but report errors */
-                       stm32x_write_flash_reg(bank, FLASH_CCR, flash_sr);
+                       stm32h7_write_flash_reg_by_index(bank, 
flash_clear_status_index, flash_sr);
                        retval = ERROR_FAIL;
                }
        }
@@ -711,8 +917,8 @@ static int stm32x_write(struct flash_bank *bank, const 
uint8_t *buffer,
        4. Wait for flash operations completion
        */
        while (blocks_remaining > 0) {
-               retval = stm32x_write_flash_reg(bank, FLASH_CR,
-                               
stm32x_info->part_info->compute_flash_cr(FLASH_PG | FLASH_PSIZE_64, 0));
+               retval = stm32h7_write_flash_reg_by_index(bank, 
STM32_FLASH_CR_INDEX,
+                               0x32);
                if (retval != ERROR_OK)
                        goto flash_lock;
 
@@ -768,6 +974,12 @@ static int stm32x_probe(struct flash_bank *bank)
        LOG_DEBUG("device id = 0x%08" PRIx32, stm32x_info->idcode);
 
        device_id = stm32x_info->idcode & 0xfff;
+       if (device_id == DEVID_STM32H7R_H7SXX) {
+               stm32x_info->flash_regs = stm32h7rs_flash_regs;
+       } else {
+               stm32x_info->flash_regs = stm32h7_flash_regs;
+       }
+
 
        for (unsigned int n = 0; n < ARRAY_SIZE(stm32h7x_parts); n++) {
                if (device_id == stm32h7x_parts[n].id)
@@ -828,6 +1040,7 @@ static int stm32x_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");
@@ -967,7 +1180,7 @@ static int stm32x_set_rdp(struct flash_bank *bank, enum 
stm32h7x_opt_rdp new_rdp
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_PRG, &optsr);
+       retval = stm32h7_read_flash_reg_by_index(bank, 
STM32_FLASH_OPTSR_PRG_INDEX, &optsr);
 
        if (retval != ERROR_OK) {
                LOG_DEBUG("unable to read FLASH_OPTSR_PRG register");
@@ -997,7 +1210,7 @@ static int stm32x_set_rdp(struct flash_bank *bank, enum 
stm32h7x_opt_rdp new_rdp
        optsr = (optsr & ~OPT_RDP_MASK) | (new_rdp << OPT_RDP_POS);
 
        /* apply new option value */
-       return stm32x_write_option(bank, FLASH_OPTSR_PRG, optsr);
+       return stm32x_write_option(bank, STM32_FLASH_OPTSR_PRG_INDEX, optsr);
 }
 
 COMMAND_HANDLER(stm32x_handle_lock_command)
@@ -1045,6 +1258,20 @@ static int stm32x_mass_erase(struct flash_bank *bank)
        int retval, retval2;
        struct target *target = bank->target;
        struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
+       uint32_t device_id = stm32x_info->idcode & 0xFFF;
+       uint32_t mass_erase_flags1;
+       uint32_t mass_erase_flags2;
+
+
+       if (device_id == DEVID_STM32H7R_H7SXX) {
+               mass_erase_flags1 = FLASH_BER;
+               mass_erase_flags2 = FLASH_BER | H7RS_FLASH_START;
+       } else {
+               mass_erase_flags1 = FLASH_BER | FLASH_PSIZE_64;
+               mass_erase_flags2 = FLASH_BER | FLASH_PSIZE_64 | FLASH_START;
+       }
+
+
 
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
@@ -1056,17 +1283,17 @@ static int stm32x_mass_erase(struct flash_bank *bank)
                goto flash_lock;
 
        /* mass erase flash memory bank */
-       retval = stm32x_write_flash_reg(bank, FLASH_CR,
-                       stm32x_info->part_info->compute_flash_cr(FLASH_BER | 
FLASH_PSIZE_64, 0));
+       retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
+                       
stm32x_info->part_info->compute_flash_cr(mass_erase_flags1, 0));
        if (retval != ERROR_OK)
                goto flash_lock;
 
-       retval = stm32x_write_flash_reg(bank, FLASH_CR,
-                       stm32x_info->part_info->compute_flash_cr(FLASH_BER | 
FLASH_PSIZE_64 | FLASH_START, 0));
+       retval = stm32h7_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX,
+                       
stm32x_info->part_info->compute_flash_cr(mass_erase_flags2, 0));
        if (retval != ERROR_OK)
                goto flash_lock;
 
-       retval = stm32x_wait_flash_op_queue(bank, 30000);
+       retval = stm32x_wait_flash_op_queue(bank, MASS_ERASE_TIMEOUT);
        if (retval != ERROR_OK)
                goto flash_lock;
 
diff --git a/tcl/target/stm32h7rx.cfg b/tcl/target/stm32h7rx.cfg
new file mode 100644
index 0000000000..9aa322eb36
--- /dev/null
+++ b/tcl/target/stm32h7rx.cfg
@@ -0,0 +1,162 @@
+# 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
+}
+
+#      swo  create $_CHIPNAME.swo  -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 
0xE00E3000
+#      tpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 
0xE00F5000
+
+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
+
+       # Stop watchdog counters during halt
+       # DBGMCU_APB3FZ1 |= WWDG1
+       # stm32h7x_dbgmcu_mmw 0x034 0x00000040 0
+       # DBGMCU_APB1LFZ1 |= WWDG2
+       # stm32h7x_dbgmcu_mmw 0x03C 0x00000800 0
+       # DBGMCU_APB4FZ1 |= WDGLSD1 | WDGLSD2
+       # stm32h7x_dbgmcu_mmw 0x054 0x000C0000 0
+
+       # Enable clock for tracing
+       # DBGMCU_CR |= TRACECLKEN
+       stm32h7x_dbgmcu_mmw 0x004 0x00100000 0
+
+       # RM0399 (id 0x450) M7+M4 with SWO Funnel
+       # RM0433 (id 0x450) M7 with SWO Funnel
+       # RM0455 (id 0x480) M7 without SWO Funnel
+       # RM0468 (id 0x483) M7 without SWO Funnel
+       # Enable CM7 and CM4 slave ports in SWO trace Funnel
+       # Works ok also on devices single core and without SWO funnel
+       # Hack, use stm32h7x_dbgmcu_mmw with big offset to control SWTF
+       # SWTF_CTRL |= ENS0 | ENS1
+       # stm32h7x_dbgmcu_mmw 0x3000 0x00000003 0
+}
+
+$_CHIPNAME.cpu0 configure -event reset-init {
+       # Clock after reset is HSI at 64 MHz, no need of PLL
+       adapter speed 4000
+}
+
+# get _CHIPNAME from current target
+proc stm32h7x_get_chipname {} {
+       set t [target current]
+       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}]
+
+       # set used_target $_CHIPNAME.ap0
+       # set reg_addr [expr {0xE00E1000 + $reg_offset}]
+
+       stm32h7x_mmw $used_target $reg_addr $setbits $clearbits
+}

-- 


Reply via email to