This is an automated email from Gerrit.

Tarek BOCHKATI ([email protected]) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/5441

-- gerrit

commit 952c7f6054409b7529fe131fc51addef4173bdcf
Author: Tarek BOCHKATI <[email protected]>
Date:   Thu Feb 6 23:38:06 2020 +0100

    flash/stm32h7x: add support of STM32H7Ax/H7Bx devices [WIP]
    
    this new device has the following features:
     - single core cortex-M7
     - 2MB flash - dual bank
        - page size 8k
        - write protection grouped by 4 sectors
        - write block size 128 bits (16 bytes) => TODO
    
    the bit definition of FLASH_CR is different than STM32H74x,
    that's why we introduced a helper to compute the FLASH_CR value
    
    Change-Id: I4da10cde8dd215b1b0f2645f0efdba9d198038d1
    Signed-off-by: Tarek BOCHKATI <[email protected]>

diff --git a/contrib/loaders/flash/stm32/stm32h7x.S 
b/contrib/loaders/flash/stm32/stm32h7x.S
index beb8fdb..763374b 100644
--- a/contrib/loaders/flash/stm32/stm32h7x.S
+++ b/contrib/loaders/flash/stm32/stm32h7x.S
@@ -47,7 +47,7 @@
 
 #define STM32_FLASH_CR_OFFSET  0x0C    /* offset of CR register in FLASH 
struct */
 #define STM32_FLASH_SR_OFFSET  0x10    /* offset of SR register in FLASH 
struct */
-#define STM32_CR_PROG                  0x00000032      /* PSIZE64 | PG */
+#define STM32_CR_PROG                  0x00000002      /* PG */
 #define STM32_SR_QW_MASK               0x00000004      /* QW */
 #define STM32_SR_ERROR_MASK            0x07ee0000      /* DBECCERR | SNECCERR 
| RDSERR | RDPERR | OPERR
                                                                                
           | INCERR | STRBERR | PGSERR | WRPERR */
diff --git a/contrib/loaders/flash/stm32/stm32h7x.inc 
b/contrib/loaders/flash/stm32/stm32h7x.inc
index ec14de0..b14aefa 100644
--- a/contrib/loaders/flash/stm32/stm32h7x.inc
+++ b/contrib/loaders/flash/stm32/stm32h7x.inc
@@ -1,6 +1,6 @@
 /* Autogenerated with ../../../../src/helper/bin2char.sh */
 
0x45,0x68,0x06,0x68,0x36,0xb3,0x76,0x1b,0x42,0xbf,0x76,0x18,0x36,0x1a,0x08,0x3e,
-0x20,0x2e,0xf6,0xd3,0x4f,0xf0,0x32,0x06,0xe6,0x60,0x4f,0xf0,0x08,0x07,0xbf,0xf3,
+0x20,0x2e,0xf6,0xd3,0x4f,0xf0,0x02,0x06,0xe6,0x60,0x4f,0xf0,0x08,0x07,0xbf,0xf3,
 
0x4f,0x8f,0x55,0xf8,0x04,0x6b,0x42,0xf8,0x04,0x6b,0xbf,0xf3,0x4f,0x8f,0x8d,0x42,
 
0x28,0xbf,0x00,0xf1,0x08,0x05,0x01,0x3f,0xf1,0xd1,0x26,0x69,0x16,0xf0,0x04,0x0f,
 
0xfb,0xd1,0x05,0x4f,0x3e,0x42,0x03,0xd1,0x45,0x60,0x01,0x3b,0xd9,0xd1,0x01,0xe0,
diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c
index 61e9b3e..b22cfd2 100644
--- a/src/flash/nor/stm32h7x.c
+++ b/src/flash/nor/stm32h7x.c
@@ -57,8 +57,6 @@
 #define FLASH_FW       (1 << 6)
 #define FLASH_START    (1 << 7)
 
-#define FLASH_SNB(a)   ((a) << 8)
-
 /* FLASH_SR register bits */
 #define FLASH_BSY      (1 << 0)  /* Operation in progress */
 #define FLASH_QW       (1 << 2)  /* Operation queue in progress */
@@ -100,7 +98,6 @@
 #define FLASH_BANK1_ADDRESS     0x08100000
 #define FLASH_REG_BASE_B0       0x52002000
 #define FLASH_REG_BASE_B1       0x52002100
-#define FLASH_SIZE_ADDRESS      0x1FF1E880
 #define FLASH_BLOCK_SIZE        32
 
 struct stm32h7x_rev {
@@ -119,6 +116,10 @@ struct stm32h7x_part_info {
        uint16_t first_bank_size_kb; /* Used when has_dual_bank is true */
        uint32_t flash_regs_base;    /* Flash controller registers location */
        uint32_t fsize_addr;         /* Location of FSIZE register */
+       const uint32_t wps_group_size; /* write protection group sectors' count 
*/
+       const uint32_t wps_mask;
+       /* function to compute flash_cr register values */
+       uint32_t (*compute_flash_cr)(uint32_t cmd, int snb);
 };
 
 struct stm32h7x_flash_bank {
@@ -139,6 +140,26 @@ static const struct stm32h7x_rev stm32_450_revs[] = {
        { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X"  }, { 
0x2003, "V"  },
 };
 
+static const struct stm32h7x_rev stm32_480_revs[] = {
+       { 0x1000, "A"},
+};
+
+static uint32_t stm32x_compute_flash_cr_450(uint32_t cmd, int snb)
+{
+       return cmd | (snb << 8);
+}
+
+static uint32_t stm32x_compute_flash_cr_480(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);
+
+       /* mask parallelism, FW and START bits */
+       cmd &= ~(FLASH_PSIZE_64 | FLASH_FW | FLASH_START);
+
+       return cmd | (tmp >> 2) | (snb << 6);
+}
+
 static const struct stm32h7x_part_info stm32h7x_parts[] = {
        {
        .id                                     = 0x450,
@@ -150,7 +171,25 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
        .first_bank_size_kb     = 1024,
        .has_dual_bank          = 1,
        .flash_regs_base        = FLASH_REG_BASE_B0,
-       .fsize_addr                     = FLASH_SIZE_ADDRESS,
+       .fsize_addr                     = 0x1FF1E880,
+       .wps_group_size         = 1,
+       .wps_mask                       = 0xFF,
+       .compute_flash_cr       = stm32x_compute_flash_cr_450,
+       },
+       {
+       .id                                     = 0x480,
+       .revs                           = stm32_480_revs,
+       .num_revs                       = ARRAY_SIZE(stm32_480_revs),
+       .device_str                     = "STM32H7Ax/7Bx",
+       .page_size                      = 8,  /* 8 KB */
+       .max_flash_size_kb      = 2048,
+       .first_bank_size_kb     = 1024,
+       .has_dual_bank          = 1,
+       .flash_regs_base        = FLASH_REG_BASE_B0,
+       .fsize_addr                     = 0x08FFF80C,
+       .wps_group_size         = 4,
+       .wps_mask                       = 0xFFFFFFFF,
+       .compute_flash_cr       = stm32x_compute_flash_cr_480,
        },
 };
 
@@ -348,7 +387,7 @@ static int stm32x_write_option(struct flash_bank *bank, 
uint32_t reg_offset, uin
        int timeout = FLASH_ERASE_TIMEOUT;
        for (;;) {
                uint32_t status;
-               retval = stm32x_read_flash_reg(bank, FLASH_OPTSR_CUR, &status);
+               retval = stm32x_get_flash_status(bank, &status);
                if (retval != ERROR_OK) {
                        LOG_ERROR("stm32x_options_program: failed to read 
FLASH_OPTSR_CUR");
                        goto flash_options_lock;
@@ -396,14 +435,15 @@ static int stm32x_protect_check(struct flash_bank *bank)
                return retval;
        }
 
-       for (int i = 0; i < bank->num_sectors; i++) {
-               bank->sectors[i].is_protected = protection & (1 << i) ? 0 : 1;
+       for (int i = 0; i < bank->num_prot_blocks; i++) {
+               bank->prot_blocks[i].is_protected = protection & (1 << i) ? 0 : 
1;
        }
        return ERROR_OK;
 }
 
 static int stm32x_erase(struct flash_bank *bank, int first, int last)
 {
+       struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
        int retval, retval2;
 
        assert(first < bank->num_sectors);
@@ -429,13 +469,13 @@ static int stm32x_erase(struct flash_bank *bank, int 
first, int last)
        for (int i = first; i <= last; i++) {
                LOG_DEBUG("erase sector %d", i);
                retval = stm32x_write_flash_reg(bank, FLASH_CR,
-                               FLASH_SER | FLASH_SNB(i) | FLASH_PSIZE_64);
+                               
stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64, i));
                if (retval != ERROR_OK) {
                        LOG_ERROR("Error erase sector %d", i);
                        goto flash_lock;
                }
                retval = stm32x_write_flash_reg(bank, FLASH_CR,
-                               FLASH_SER | FLASH_SNB(i) | FLASH_PSIZE_64 | 
FLASH_START);
+                               
stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64 | 
FLASH_START, i));
                if (retval != ERROR_OK) {
                        LOG_ERROR("Error erase sector %d", i);
                        goto flash_lock;
@@ -598,6 +638,7 @@ static int stm32x_write(struct flash_bank *bank, const 
uint8_t *buffer,
                uint32_t offset, uint32_t count)
 {
        struct target *target = bank->target;
+       struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
        uint32_t address = bank->base + offset;
        int retval, retval2;
 
@@ -646,7 +687,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, FLASH_PG | 
FLASH_PSIZE_64);
+               retval = stm32x_write_flash_reg(bank, FLASH_CR,
+                               
stm32x_info->part_info->compute_flash_cr(FLASH_PG | FLASH_PSIZE_64, 0));
                if (retval != ERROR_OK)
                        goto flash_lock;
 
@@ -671,16 +713,6 @@ flash_lock:
        return (retval == ERROR_OK) ? retval2 : retval;
 }
 
-static void setup_sector(struct flash_bank *bank, int start, int num, int size)
-{
-       for (int i = start; i < (start + num) ; i++) {
-               assert(i < bank->num_sectors);
-               bank->sectors[i].offset = bank->size;
-               bank->sectors[i].size = size;
-               bank->size += bank->sectors[i].size;
-       }
-}
-
 static int stm32x_read_id_code(struct flash_bank *bank, uint32_t *id)
 {
        /* read stm32 device id register */
@@ -694,7 +726,6 @@ static int stm32x_probe(struct flash_bank *bank)
 {
        struct target *target = bank->target;
        struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
-       int i;
        uint16_t flash_size_in_kb;
        uint32_t device_id;
        uint32_t base_address = FLASH_BANK0_ADDRESS;
@@ -773,34 +804,47 @@ static int stm32x_probe(struct flash_bank *bank)
        /* did we assign flash size? */
        assert(flash_size_in_kb != 0xffff);
 
-       /* calculate numbers of pages */
-       int num_pages = flash_size_in_kb / stm32x_info->part_info->page_size;
+       bank->base = base_address;
+       bank->size = flash_size_in_kb * 1024;
 
-       /* check that calculation result makes sense */
-       assert(num_pages > 0);
+       /* setup sectors */
+       bank->num_sectors = flash_size_in_kb / 
stm32x_info->part_info->page_size;
+       assert(bank->num_sectors > 0);
 
        if (bank->sectors) {
                free(bank->sectors);
                bank->sectors = NULL;
        }
 
-       bank->base = base_address;
-       bank->num_sectors = num_pages;
-       bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
+       bank->sectors = alloc_block_array(0, stm32x_info->part_info->page_size 
* 1024,
+                       bank->num_sectors);
+
        if (bank->sectors == NULL) {
                LOG_ERROR("failed to allocate bank sectors");
                return ERROR_FAIL;
        }
-       bank->size = 0;
 
-       /* fixed memory */
-       setup_sector(bank, 0, num_pages, stm32x_info->part_info->page_size * 
1024);
+       /* setup protection blocks */
+       const uint32_t wpsn = stm32x_info->part_info->wps_group_size;
+       assert(bank->num_sectors % wpsn == 0);
+
+       bank->num_prot_blocks = bank->num_sectors / wpsn;
+       assert(bank->num_prot_blocks > 0);
 
-       for (i = 0; i < num_pages; i++) {
-               bank->sectors[i].is_erased = -1;
-               bank->sectors[i].is_protected = 0;
+       if (bank->prot_blocks) {
+               free(bank->prot_blocks);
+               bank->prot_blocks = NULL;
        }
 
+       bank->prot_blocks = alloc_block_array(0, 
stm32x_info->part_info->page_size * wpsn * 1024,
+                       bank->num_prot_blocks);
+
+       if (bank->prot_blocks == NULL) {
+               LOG_ERROR("failed to allocate bank prot_block");
+               return ERROR_FAIL;
+       }
+
+
        stm32x_info->probed = 1;
        return ERROR_OK;
 }
@@ -940,6 +984,7 @@ 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;
 
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
@@ -951,11 +996,13 @@ 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, FLASH_BER | 
FLASH_PSIZE_64);
+       retval = stm32x_write_flash_reg(bank, FLASH_CR,
+                       stm32x_info->part_info->compute_flash_cr(FLASH_BER | 
FLASH_PSIZE_64, 0));
        if (retval != ERROR_OK)
                goto flash_lock;
 
-       retval = stm32x_write_flash_reg(bank, FLASH_CR, FLASH_BER | 
FLASH_PSIZE_64 | FLASH_START);
+       retval = stm32x_write_flash_reg(bank, FLASH_CR,
+                       stm32x_info->part_info->compute_flash_cr(FLASH_BER | 
FLASH_PSIZE_64 | FLASH_START, 0));
        if (retval != ERROR_OK)
                goto flash_lock;
 

-- 


_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to