flash Kinetis: add KV5x family 00/3900/3
authorTomas Vanek <vanekt@fbl.cz>
Sat, 3 Dec 2016 11:14:10 +0000 (12:14 +0100)
committerFreddie Chopin <freddie.chopin@gmail.com>
Sat, 17 Jun 2017 11:01:04 +0000 (12:01 +0100)
Real time control MCU has a Cortex-M7 and numerous changes in flash layout.
Introduced a new ID of MDM-AP.

While on it a LOG_DEBUG format error fixed.

Change-Id: I1018660ce0c3dd63ac5e2563408fabff3c3daef7
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/3900
Tested-by: jenkins
Reviewed-by: Joakim NohlgÄrd <joakim.nohlgard@eistec.se>
Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
src/flash/nor/kinetis.c

index 08f011df4ce6c89ca279c043234d5c0a1cbad2da..d386b1bdb41535878a336109fda6aca2b9447f75 100644 (file)
 #define KINETIS_SDID_FAMILYID_K2X   0x20000000
 #define KINETIS_SDID_FAMILYID_K3X   0x30000000
 #define KINETIS_SDID_FAMILYID_K4X   0x40000000
+#define KINETIS_SDID_FAMILYID_K5X   0x50000000
 #define KINETIS_SDID_FAMILYID_K6X   0x60000000
 #define KINETIS_SDID_FAMILYID_K7X   0x70000000
 #define KINETIS_SDID_FAMILYID_K8X   0x80000000
@@ -228,10 +229,6 @@ struct kinetis_flash_bank {
                                        /* same as bank->base for pflash, differs for FlexNVM */
        uint32_t protection_block;      /* number of first protection block in this bank */
 
-       uint32_t sim_sdid;
-       uint32_t sim_fcfg1;
-       uint32_t sim_fcfg2;
-
        enum {
                FC_AUTO = 0,
                FC_PFLASH,
@@ -247,7 +244,15 @@ struct kinetis_flash_bank {
                FS_INVALIDATE_CACHE_L = 0x10,   /* using MCM->PLACR */
                FS_INVALIDATE_CACHE_MSCM = 0x20,
                FS_NO_CMD_BLOCKSTAT = 0x40,
+               FS_WIDTH_256BIT = 0x80,
        } flash_support;
+
+       /* device parameters - should be same for all probed banks of one device */
+       uint32_t sim_sdid;
+       uint32_t sim_fcfg1;
+       uint32_t sim_fcfg2;
+
+       uint32_t progr_accel_ram;
 };
 
 #define MDM_AP                 1
@@ -605,6 +610,7 @@ deassert_reset_and_exit:
 static const uint32_t kinetis_known_mdm_ids[] = {
        0x001C0000,     /* Kinetis-K Series */
        0x001C0020,     /* Kinetis-L/M/V/E Series */
+       0x001C0030,     /* Kinetis with a Cortex-M7, in time of writing KV58 */
 };
 
 /*
@@ -1251,7 +1257,7 @@ static int kinetis_erase(struct flash_bank *bank, int first, int last)
 
                bank->sectors[i].is_erased = 1;
 
-               if (bank->base == 0
+               if (kinfo->prog_base == 0
                        && bank->sectors[i].offset <= FCF_ADDRESS
                        && bank->sectors[i].offset + bank->sectors[i].size > FCF_ADDRESS + FCF_SIZE) {
                        if (allow_fcf_writes) {
@@ -1346,13 +1352,13 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer
                        memset(buffer_aligned, 0xff, size_aligned);
                        memcpy(buffer_aligned + align_begin, buffer, size);
 
-                       result = target_write_memory(bank->target, FLEXRAM,
+                       result = target_write_memory(bank->target, kinfo->progr_accel_ram,
                                                4, size_aligned / 4, buffer_aligned);
 
                        LOG_DEBUG("section @ %08" PRIx32 " aligned begin %" PRIu32 ", end %" PRIu32,
                                        bank->base + offset, align_begin, align_end);
                } else
-                       result = target_write_memory(bank->target, FLEXRAM,
+                       result = target_write_memory(bank->target, kinfo->progr_accel_ram,
                                                4, size_aligned / 4, buffer);
 
                LOG_DEBUG("write section @ %08" PRIx32 " with length %" PRIu32 " bytes",
@@ -1374,8 +1380,16 @@ static int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer
                        break;
                }
 
-               if (ftfx_fstat & 0x01)
+               if (ftfx_fstat & 0x01) {
                        LOG_ERROR("Flash write error at %08" PRIx32, bank->base + offset);
+                       if (kinfo->prog_base == 0 && offset == FCF_ADDRESS + FCF_SIZE
+                                       && (kinfo->flash_support & FS_WIDTH_256BIT)) {
+                               LOG_ERROR("Flash write immediately after the end of Flash Config Field shows error");
+                               LOG_ERROR("because the flash memory is 256 bits wide (data were written correctly).");
+                               LOG_ERROR("Either change the linker script to add a gap of 16 bytes after FCF");
+                               LOG_ERROR("or set 'kinetis fcf_source write'");
+                       }
+               }
 
                buffer += size;
                offset += size;
@@ -1405,7 +1419,7 @@ static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,
                }
        }
 
-       LOG_DEBUG("flash write @08%" PRIx32, bank->base + offset);
+       LOG_DEBUG("flash write @ %08" PRIx32, bank->base + offset);
 
        if (fallback == 0) {
                /* program section command */
@@ -1488,6 +1502,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
        int result;
        bool set_fcf = false;
        int sect = 0;
+       struct kinetis_flash_bank *kinfo = bank->driver_priv;
 
        result = kinetis_check_run_mode(bank->target);
        if (result != ERROR_OK)
@@ -1498,7 +1513,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
        if (result != ERROR_OK)
                return result;
 
-       if (bank->base == 0 && !allow_fcf_writes) {
+       if (kinfo->prog_base == 0 && !allow_fcf_writes) {
                if (bank->sectors[1].offset <= FCF_ADDRESS)
                        sect = 1;       /* 1kb sector, FCF in 2nd sector */
 
@@ -1520,7 +1535,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
                                return result;
                }
 
-               result = target_read_memory(bank->target, FCF_ADDRESS, 4, FCF_SIZE / 4, fcf_current);
+               result = target_read_memory(bank->target, bank->base + FCF_ADDRESS, 4, FCF_SIZE / 4, fcf_current);
                if (result == ERROR_OK && memcmp(fcf_current, fcf_buffer, FCF_SIZE) == 0)
                        set_fcf = false;
 
@@ -1555,10 +1570,12 @@ static int kinetis_probe(struct flash_bank *bank)
        uint32_t nvm_size = 0, pf_size = 0, df_size = 0, ee_size = 0;
        unsigned num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0, first_nvm_bank = 0,
                        pflash_sector_size_bytes = 0, nvm_sector_size_bytes = 0;
+       unsigned maxaddr_shift = 13;
        struct target *target = bank->target;
        struct kinetis_flash_bank *kinfo = bank->driver_priv;
 
        kinfo->probed = false;
+       kinfo->progr_accel_ram = FLEXRAM;
 
        result = target_read_u32(target, SIM_SDID, &kinfo->sim_sdid);
        if (result != ERROR_OK)
@@ -1771,6 +1788,19 @@ static int kinetis_probe(struct flash_bank *bank)
                                kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
                                break;
 
+                       case KINETIS_SDID_FAMILYID_K5X | KINETIS_SDID_SUBFAMID_KX6:
+                       case KINETIS_SDID_FAMILYID_K5X | KINETIS_SDID_SUBFAMID_KX8:
+                               /* KV5x: FTFE, 8kB sectors */
+                               pflash_sector_size_bytes = 8<<10;
+                               maxaddr_shift = 14;
+                               kinfo->max_flash_prog_size = 1<<10;
+                               num_blocks = 1;
+                               kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_WIDTH_256BIT;
+                               bank->base = 0x10000000;
+                               kinfo->prog_base = 0;
+                               kinfo->progr_accel_ram = 0x18000000;
+                               break;
+
                        default:
                                LOG_ERROR("Unsupported KV FAMILYID SUBFAMID");
                        }
@@ -1931,9 +1961,9 @@ static int kinetis_probe(struct flash_bank *bank)
                 * Checking fcfg2_maxaddr0 later in this routine is pointless then
                 */
                if (fcfg2_pflsh)
-                       pf_size = ((uint32_t)fcfg2_maxaddr0 << 13) * num_blocks;
+                       pf_size = ((uint32_t)fcfg2_maxaddr0 << maxaddr_shift) * num_blocks;
                else
-                       pf_size = ((uint32_t)fcfg2_maxaddr0 << 13) * num_blocks / 2;
+                       pf_size = ((uint32_t)fcfg2_maxaddr0 << maxaddr_shift) * num_blocks / 2;
                if (pf_size != 2048<<10)
                        LOG_WARNING("SIM_FCFG1 PFSIZE = 0xf: please check if pflash is %u KB", pf_size>>10);
 
@@ -1959,8 +1989,10 @@ static int kinetis_probe(struct flash_bank *bank)
                /* pflash, banks start at address zero */
                kinfo->flash_class = FC_PFLASH;
                bank->size = (pf_size / num_pflash_blocks);
-               bank->base = 0x00000000 + bank->size * bank->bank_number;
-               kinfo->prog_base = bank->base;
+               if (bank->base == 0) {
+                       bank->base = 0x00000000 + bank->size * bank->bank_number;
+                       kinfo->prog_base = bank->base;
+               }
                kinfo->sector_size = pflash_sector_size_bytes;
                /* pflash is divided into 32 protection areas for
                 * parts with more than 32K of PFlash. For parts with
@@ -2013,16 +2045,16 @@ static int kinetis_probe(struct flash_bank *bank)
                return ERROR_FLASH_BANK_INVALID;
        }
 
-       if (bank->bank_number == 0 && ((uint32_t)fcfg2_maxaddr0 << 13) != bank->size)
+       if (bank->bank_number == 0 && ((uint32_t)fcfg2_maxaddr0 << maxaddr_shift) != bank->size)
                LOG_WARNING("MAXADDR0 0x%02" PRIx8 " check failed,"
                                " please report to OpenOCD mailing list", fcfg2_maxaddr0);
        if (fcfg2_pflsh) {
-               if (bank->bank_number == 1 && ((uint32_t)fcfg2_maxaddr1 << 13) != bank->size)
+               if (bank->bank_number == 1 && ((uint32_t)fcfg2_maxaddr1 << maxaddr_shift) != bank->size)
                        LOG_WARNING("MAXADDR1 0x%02" PRIx8 " check failed,"
                                " please report to OpenOCD mailing list", fcfg2_maxaddr1);
        } else {
                if ((unsigned)bank->bank_number == first_nvm_bank
-                               && ((uint32_t)fcfg2_maxaddr1 << 13) != df_size)
+                               && ((uint32_t)fcfg2_maxaddr1 << maxaddr_shift) != df_size)
                        LOG_WARNING("FlexNVM MAXADDR1 0x%02" PRIx8 " check failed,"
                                " please report to OpenOCD mailing list", fcfg2_maxaddr1);
        }

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)