flash/stm32l4x: fix dual bank support for STM32L552xC devices
[openocd.git] / src / flash / nor / stm32l4x.c
index e4d291e6dc4323a44d5e5ea0a73513772dfb9be0..8c292e76d5be7318aefbfef880433dc7b1a70c2f 100644 (file)
@@ -1405,16 +1405,19 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,
        armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
        armv7m_info.core_mode = ARM_MODE_THREAD;
 
-       init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */
+       /* contrib/loaders/flash/stm32/stm32l4x.c:write() arguments */
+       init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* stm32l4_work_area ptr , status (out) */
        init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);    /* buffer end */
        init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);    /* target address */
        init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);    /* count (of stm32l4_info->data_width) */
-       init_reg_param(&reg_params[4], "sp", 32, PARAM_OUT);    /* write algo stack pointer */
 
        buf_set_u32(reg_params[0].value, 0, 32, source->address);
        buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
        buf_set_u32(reg_params[2].value, 0, 32, address);
        buf_set_u32(reg_params[3].value, 0, 32, count);
+
+       /* write algo stack pointer */
+       init_reg_param(&reg_params[4], "sp", 32, PARAM_OUT);
        buf_set_u32(reg_params[4].value, 0, 32, source->address +
                        offsetof(struct stm32l4_work_area, stack) + LDR_STACK_SIZE);
 
@@ -1646,7 +1649,10 @@ static int stm32l4_read_idcode(struct flash_bank *bank, uint32_t *id)
 
        struct cortex_m_common *cortex_m = target_to_cm(bank->target);
 
-       if (cortex_m->core_info->partno == CORTEX_M0P_PARTNO && cortex_m->armv7m.debug_ap->ap_num == 1) {
+       /* CPU2 (Cortex-M0+) is supported only with non-hla adapters because it is on AP1.
+        * Using HLA adapters armv7m.debug_ap is null, and checking ap_num triggers a segfault */
+       if (cortex_m->core_info->partno == CORTEX_M0P_PARTNO &&
+                       cortex_m->armv7m.debug_ap && cortex_m->armv7m.debug_ap->ap_num == 1) {
                uint32_t uid64_ids;
 
                /* UID64 is contains
@@ -1815,6 +1821,8 @@ static int stm32l4_probe(struct flash_bank *bank)
        /* did we assign a flash size? */
        assert((flash_size_kb != 0xffff) && flash_size_kb);
 
+       const bool is_max_flash_size = flash_size_kb == stm32l4_info->part_info->max_flash_size_kb;
+
        stm32l4_info->bank1_sectors = 0;
        stm32l4_info->hole_sectors = 0;
 
@@ -1822,7 +1830,6 @@ static int stm32l4_probe(struct flash_bank *bank)
        int page_size_kb = 0;
 
        stm32l4_info->dual_bank_mode = false;
-       bool use_dbank_bit = false;
 
        switch (device_id) {
        case DEVID_STM32L47_L48XX:
@@ -1839,8 +1846,8 @@ static int stm32l4_probe(struct flash_bank *bank)
                num_pages = flash_size_kb / page_size_kb;
                stm32l4_info->bank1_sectors = num_pages;
 
-               /* check DUAL_BANK bit[21] if the flash is less than 1M */
-               if (flash_size_kb == 1024 || (stm32l4_info->optr & BIT(21))) {
+               /* check DUAL_BANK option bit if the flash is less than 1M */
+               if (is_max_flash_size || (stm32l4_info->optr & FLASH_L4_DUAL_BANK)) {
                        stm32l4_info->dual_bank_mode = true;
                        stm32l4_info->bank1_sectors = num_pages / 2;
                }
@@ -1860,14 +1867,14 @@ static int stm32l4_probe(struct flash_bank *bank)
                stm32l4_info->bank1_sectors = num_pages;
                break;
        case DEVID_STM32G0B_G0CXX:
-               /* single/dual bank depending on bit(21) */
+               /* single/dual bank depending on DUAL_BANK option bit */
                page_size_kb = 2;
                num_pages = flash_size_kb / page_size_kb;
                stm32l4_info->bank1_sectors = num_pages;
                stm32l4_info->cr_bker_mask = FLASH_BKER_G0;
 
                /* check DUAL_BANK bit */
-               if (stm32l4_info->optr & BIT(21)) {
+               if (stm32l4_info->optr & FLASH_G0_DUAL_BANK) {
                        stm32l4_info->sr_bsy_mask = FLASH_BSY | FLASH_BSY2;
                        stm32l4_info->dual_bank_mode = true;
                        stm32l4_info->bank1_sectors = num_pages / 2;
@@ -1881,7 +1888,7 @@ static int stm32l4_probe(struct flash_bank *bank)
                page_size_kb = 4;
                num_pages = flash_size_kb / page_size_kb;
                stm32l4_info->bank1_sectors = num_pages;
-               if (stm32l4_info->optr & BIT(22)) {
+               if (stm32l4_info->optr & FLASH_G4_DUAL_BANK) {
                        stm32l4_info->dual_bank_mode = true;
                        page_size_kb = 2;
                        num_pages = flash_size_kb / page_size_kb;
@@ -1895,18 +1902,17 @@ static int stm32l4_probe(struct flash_bank *bank)
        case DEVID_STM32L4R_L4SXX:
        case DEVID_STM32L4P_L4QXX:
                /* STM32L4R/S can be single/dual bank:
-                *   if size = 2M check DBANK bit(22)
-                *   if size = 1M check DB1M bit(21)
+                *   if size = 2M check DBANK bit
+                *   if size = 1M check DB1M bit
                 * STM32L4P/Q can be single/dual bank
-                *   if size = 1M check DBANK bit(22)
-                *   if size = 512K check DB512K bit(21)
+                *   if size = 1M check DBANK bit
+                *   if size = 512K check DB512K bit (same as DB1M bit)
                 */
                page_size_kb = 8;
                num_pages = flash_size_kb / page_size_kb;
                stm32l4_info->bank1_sectors = num_pages;
-               use_dbank_bit = flash_size_kb == part_info->max_flash_size_kb;
-               if ((use_dbank_bit && (stm32l4_info->optr & BIT(22))) ||
-                       (!use_dbank_bit && (stm32l4_info->optr & BIT(21)))) {
+               if ((is_max_flash_size && (stm32l4_info->optr & FLASH_L4R_DBANK)) ||
+                       (!is_max_flash_size && (stm32l4_info->optr & FLASH_LRR_DB1M))) {
                        stm32l4_info->dual_bank_mode = true;
                        page_size_kb = 4;
                        num_pages = flash_size_kb / page_size_kb;
@@ -1915,29 +1921,30 @@ static int stm32l4_probe(struct flash_bank *bank)
                break;
        case DEVID_STM32L55_L56XX:
                /* STM32L55/L56xx can be single/dual bank:
-                *   if size = 512K check DBANK bit(22)
-                *   if size = 256K check DB256K bit(21)
+                *   if size = 512K check DBANK bit
+                *   if size = 256K check DB256K bit
+                *
+                * default page size is 4kb, if DBANK = 1, the page size is 2kb.
                 */
-               page_size_kb = 4;
+
+               page_size_kb = (stm32l4_info->optr & FLASH_L5_DBANK) ? 2 : 4;
                num_pages = flash_size_kb / page_size_kb;
                stm32l4_info->bank1_sectors = num_pages;
-               use_dbank_bit = flash_size_kb == part_info->max_flash_size_kb;
-               if ((use_dbank_bit && (stm32l4_info->optr & BIT(22))) ||
-                       (!use_dbank_bit && (stm32l4_info->optr & BIT(21)))) {
+
+               if ((is_max_flash_size && (stm32l4_info->optr & FLASH_L5_DBANK)) ||
+                       (!is_max_flash_size && (stm32l4_info->optr & FLASH_L5_DB256))) {
                        stm32l4_info->dual_bank_mode = true;
-                       page_size_kb = 2;
-                       num_pages = flash_size_kb / page_size_kb;
                        stm32l4_info->bank1_sectors = num_pages / 2;
                }
                break;
        case DEVID_STM32U57_U58XX:
                /* if flash size is max (2M) the device is always dual bank
-                * otherwise check DUALBANK bit(21)
+                * otherwise check DUALBANK
                 */
                page_size_kb = 8;
                num_pages = flash_size_kb / page_size_kb;
                stm32l4_info->bank1_sectors = num_pages;
-               if ((flash_size_kb == part_info->max_flash_size_kb) || (stm32l4_info->optr & BIT(21))) {
+               if (is_max_flash_size || (stm32l4_info->optr & FLASH_U5_DUALBANK)) {
                        stm32l4_info->dual_bank_mode = true;
                        stm32l4_info->bank1_sectors = num_pages / 2;
                }
@@ -1954,7 +1961,10 @@ static int stm32l4_probe(struct flash_bank *bank)
                page_size_kb = 2;
                num_pages = flash_size_kb / page_size_kb;
                stm32l4_info->bank1_sectors = num_pages;
-               if (armv7m->debug_ap->ap_num == 1)
+
+               /* CPU2 (Cortex-M0+) is supported only with non-hla adapters because it is on AP1.
+                * Using HLA adapters armv7m->debug_ap is null, and checking ap_num triggers a segfault */
+               if (armv7m->debug_ap && armv7m->debug_ap->ap_num == 1)
                        stm32l4_info->flash_regs = stm32wl_cpu2_flash_regs;
                break;
        default:

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)