This is an automated email from Gerrit.

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

-- gerrit

commit 3e849c8af56c9d956bec952409836055df95f280
Author: Tomas Vanek <[email protected]>
Date:   Tue Sep 29 17:48:17 2015 +0200

    kinetis: FlexNVM handling
    
    FlexNVM (data flash) is memory mapped at 0x10000000.
    Driver used to send the same address to FTFx controller for erase/write ops.
    This was wrong as FTFx accepts only low 24 bits of address.
    To fix addressing for flash controller kinfo->prog_base was introduced.
    
    Added FlexNVM protection check, blank check and data flash size calculation.
    
    Change-Id: Ia60b938266963e5d056701278cdf7bf2f62a429a
    Signed-off-by: Tomas Vanek <[email protected]>

diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c
index ba3f5ea..4b88edd 100644
--- a/src/flash/nor/kinetis.c
+++ b/src/flash/nor/kinetis.c
@@ -82,6 +82,7 @@
 #define FTFx_FCNFG     0x40020001
 #define FTFx_FCCOB3    0x40020004
 #define FTFx_FPROT3    0x40020010
+#define FTFx_FDPROT    0x40020017
 #define SIM_SDID       0x40048024
 #define SIM_SOPT1      0x40047000
 #define SIM_FCFG1      0x4004804c
@@ -190,6 +191,9 @@ struct kinetis_flash_bank {
        uint32_t sector_size;
        uint32_t max_flash_prog_size;
        uint32_t protection_size;
+       uint32_t prog_base;             /* base address for FTFx operations */
+                                       /* 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;
@@ -579,7 +583,8 @@ static int kinetis_write_block(struct flash_bank *bank, 
const uint8_t *buffer,
        uint32_t buffer_size = 2048;            /* Default minimum value */
        struct working_area *write_algorithm;
        struct working_area *source;
-       uint32_t address = bank->base + offset;
+       struct kinetis_flash_bank *kinfo = bank->driver_priv;
+       uint32_t address = kinfo->prog_base + offset;
        struct reg_param reg_params[3];
        struct armv7m_algorithm armv7m_info;
        int retval = ERROR_OK;
@@ -690,6 +695,9 @@ static int kinetis_protect(struct flash_bank *bank, int 
set, int first, int last
 static int kinetis_protect_check(struct flash_bank *bank)
 {
        struct kinetis_flash_bank *kinfo = bank->driver_priv;
+       int result;
+       int i, b;
+       uint32_t fprot, psec;
 
        if (bank->target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
@@ -697,10 +705,7 @@ static int kinetis_protect_check(struct flash_bank *bank)
        }
 
        if (kinfo->flash_class == FC_PFLASH) {
-               int result;
                uint8_t buffer[4];
-               uint32_t fprot, psec;
-               int i, b;
 
                /* read protection register */
                result = target_read_memory(bank->target, FTFx_FPROT3, 1, 4, 
buffer);
@@ -709,31 +714,39 @@ static int kinetis_protect_check(struct flash_bank *bank)
                        return result;
 
                fprot = target_buffer_get_u32(bank->target, buffer);
+               /* Every bit protects 1/32 of the full flash (not necessarily 
just this bank) */
 
-               /*
-                * Every bit protects 1/32 of the full flash (not necessarily
-                * just this bank), but we enforce the bank ordinals for
-                * PFlash to start at zero.
-                */
-               b = kinfo->bank_ordinal * (bank->size / kinfo->protection_size);
-               for (psec = 0, i = 0; i < bank->num_sectors; i++) {
-                       if ((fprot >> b) & 1)
-                               bank->sectors[i].is_protected = 0;
-                       else
-                               bank->sectors[i].is_protected = 1;
+       } else if (kinfo->flash_class == FC_FLEX_NVM) {
+               uint8_t fdprot;
 
-                       psec += bank->sectors[i].size;
+               /* read protection register */
+               result = target_read_memory(bank->target, FTFx_FDPROT, 1, 1, 
&fdprot);
+
+               if (result != ERROR_OK)
+                       return result;
+
+               fprot = fdprot;
 
-                       if (psec >= kinfo->protection_size) {
-                               psec = 0;
-                               b++;
-                       }
-               }
        } else {
-               LOG_ERROR("Protection checks for FlexNVM not yet supported");
+               LOG_ERROR("Protection checks for FlexRAM not supported");
                return ERROR_FLASH_BANK_INVALID;
        }
 
+       b = kinfo->protection_block;
+       for (psec = 0, i = 0; i < bank->num_sectors; i++) {
+               if ((fprot >> b) & 1)
+                       bank->sectors[i].is_protected = 0;
+               else
+                       bank->sectors[i].is_protected = 1;
+
+               psec += bank->sectors[i].size;
+
+               if (psec >= kinfo->protection_size) {
+                       psec = 0;
+                       b++;
+               }
+       }
+
        return ERROR_OK;
 }
 
@@ -831,6 +844,7 @@ COMMAND_HANDLER(kinetis_securing_test)
 static int kinetis_erase(struct flash_bank *bank, int first, int last)
 {
        int result, i;
+       struct kinetis_flash_bank *kinfo = bank->driver_priv;
 
        if (bank->target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
@@ -848,7 +862,7 @@ static int kinetis_erase(struct flash_bank *bank, int 
first, int last)
        for (i = first; i <= last; i++) {
                uint8_t ftfx_fstat;
                /* set command and sector address */
-               result = kinetis_ftfx_command(bank, FTFx_CMD_SECTERASE, 
bank->base + bank->sectors[i].offset,
+               result = kinetis_ftfx_command(bank, FTFx_CMD_SECTERASE, 
kinfo->prog_base + bank->sectors[i].offset,
                                0, 0, 0, 0,  0, 0, 0, 0,  &ftfx_fstat);
 
                if (result != ERROR_OK) {
@@ -988,7 +1002,7 @@ static int kinetis_write(struct flash_bank *bank, const 
uint8_t *buffer,
                        }
 
                        /* execute section-write command */
-                       result = kinetis_ftfx_command(bank, FTFx_CMD_SECTWRITE, 
bank->base + offset + i,
+                       result = kinetis_ftfx_command(bank, FTFx_CMD_SECTWRITE, 
kinfo->prog_base + offset + i,
                                        section_count>>8, section_count, 0, 0,
                                        0, 0, 0, 0,  &ftfx_fstat);
 
@@ -1032,7 +1046,7 @@ static int kinetis_write(struct flash_bank *bank, const 
uint8_t *buffer,
                                uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};
                                memcpy(padding, buffer + i, MIN(4, count-i));
 
-                               result = kinetis_ftfx_command(bank, 
FTFx_CMD_LWORDPROG, bank->base + offset + i,
+                               result = kinetis_ftfx_command(bank, 
FTFx_CMD_LWORDPROG, kinfo->prog_base + offset + i,
                                                padding[3], padding[2], 
padding[1], padding[0],
                                                0, 0, 0, 0,  &ftfx_fstat);
 
@@ -1052,8 +1066,9 @@ static int kinetis_read_part_info(struct flash_bank *bank)
 {
        int result, i;
        uint32_t offset = 0;
-       uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg2_pflsh;
-       uint32_t nvm_size = 0, pf_size = 0, ee_size = 0;
+       uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg1_depart;
+       uint8_t fcfg2_pflsh;
+       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,
                        reassign = 0, pflash_sector_size_bytes = 0, 
nvm_sector_size_bytes = 0;
        struct target *target = bank->target;
@@ -1232,7 +1247,6 @@ static int kinetis_read_part_info(struct flash_bank *bank)
        result = target_read_u32(target, SIM_FCFG2, &kinfo->sim_fcfg2);
        if (result != ERROR_OK)
                return result;
-       fcfg2_pflsh = (kinfo->sim_fcfg2 >> 23) & 0x01;
 
        LOG_DEBUG("SDID: 0x%08" PRIX32 " FCFG1: 0x%08" PRIX32 " FCFG2: 0x%08" 
PRIX32, kinfo->sim_sdid,
                        kinfo->sim_fcfg1, kinfo->sim_fcfg2);
@@ -1240,11 +1254,15 @@ static int kinetis_read_part_info(struct flash_bank 
*bank)
        fcfg1_nvmsize = (uint8_t)((kinfo->sim_fcfg1 >> 28) & 0x0f);
        fcfg1_pfsize = (uint8_t)((kinfo->sim_fcfg1 >> 24) & 0x0f);
        fcfg1_eesize = (uint8_t)((kinfo->sim_fcfg1 >> 16) & 0x0f);
+       fcfg1_depart = (uint8_t)((kinfo->sim_fcfg1 >> 8) & 0x0f);
+
+       fcfg2_pflsh = (uint8_t)((kinfo->sim_fcfg2 >> 23) & 0x01);
 
        /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
        if (!fcfg2_pflsh) {
                switch (fcfg1_nvmsize) {
                case 0x03:
+               case 0x05:
                case 0x07:
                case 0x09:
                case 0x0b:
@@ -1279,6 +1297,30 @@ static int kinetis_read_part_info(struct flash_bank 
*bank)
                        ee_size = 0;
                        break;
                }
+
+               switch (fcfg1_depart) {
+               case 0x01:
+               case 0x02:
+               case 0x03:
+               case 0x04:
+               case 0x05:
+               case 0x06:
+                       df_size = nvm_size - (4096 << fcfg1_depart);
+                       break;
+               case 0x08:
+                       df_size = 0;
+                       break;
+               case 0x09:
+               case 0x0a:
+               case 0x0b:
+               case 0x0c:
+               case 0x0d:
+                       df_size = 4096 << (fcfg1_depart & 0x7);
+                       break;
+               default:
+                       df_size = nvm_size;
+                       break;
+               }
        }
 
        switch (fcfg1_pfsize) {
@@ -1399,15 +1441,32 @@ static int kinetis_read_part_info(struct flash_bank 
*bank)
                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;
                kinfo->sector_size = pflash_sector_size_bytes;
                kinfo->protection_size = pf_size / 32;
+               kinfo->protection_block = (32 / num_pflash_blocks) * 
bank->bank_number;
+
        } else if ((unsigned)bank->bank_number < num_blocks) {
                /* nvm, banks start at address 0x10000000 */
                kinfo->flash_class = FC_FLEX_NVM;
                bank->size = (nvm_size / num_nvm_blocks);
                bank->base = 0x10000000 + bank->size * (bank->bank_number - 
first_nvm_bank);
+               kinfo->prog_base = 0x00800000 + bank->size * (bank->bank_number 
- first_nvm_bank);
                kinfo->sector_size = nvm_sector_size_bytes;
-               kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART 
bits, chip */
+               if (df_size == 0) {
+                       kinfo->protection_size = 0;
+               } else {
+                       for (i = df_size; ~i & 1; i >>= 1)
+                               ;
+                       if (i == 1)
+                               kinfo->protection_size = df_size / 8;   /* data 
flash size = 2^^n */
+                       else if (nvm_sector_size_bytes < 4096)
+                               kinfo->protection_size = 8 << 10;
+                       else
+                               kinfo->protection_size = 32 << 10;
+               }
+               kinfo->protection_block = (8 / num_nvm_blocks) * 
(bank->bank_number - first_nvm_bank);
+
        } else if ((unsigned)bank->bank_number == num_blocks) {
                LOG_ERROR("FlexRAM support not yet implemented");
                return ERROR_FLASH_OPER_UNSUPPORTED;
@@ -1493,12 +1552,12 @@ static int kinetis_blank_check(struct flash_bank *bank)
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       if (kinfo->flash_class == FC_PFLASH) {
+       if (kinfo->flash_class == FC_PFLASH || kinfo->flash_class == 
FC_FLEX_NVM) {
                int result;
                uint8_t ftfx_fstat;
 
                /* check if whole bank is blank */
-               result = kinetis_ftfx_command(bank, FTFx_CMD_BLOCKSTAT, 
bank->base, 0, 0, 0, 0,  0, 0, 0, 0, &ftfx_fstat);
+               result = kinetis_ftfx_command(bank, FTFx_CMD_BLOCKSTAT, 
kinfo->prog_base, 0, 0, 0, 0,  0, 0, 0, 0, &ftfx_fstat);
 
                if (result != ERROR_OK)
                        return result;
@@ -1508,7 +1567,7 @@ static int kinetis_blank_check(struct flash_bank *bank)
                        int i;
                        for (i = 0; i < bank->num_sectors; i++) {
                                /* normal margin */
-                               result = kinetis_ftfx_command(bank, 
FTFx_CMD_SECTSTAT, bank->base + bank->sectors[i].offset,
+                               result = kinetis_ftfx_command(bank, 
FTFx_CMD_SECTSTAT, kinfo->prog_base + bank->sectors[i].offset,
                                                1, 0, 0, 0,  0, 0, 0, 0, 
&ftfx_fstat);
 
                                if (result == ERROR_OK) {
@@ -1525,7 +1584,7 @@ static int kinetis_blank_check(struct flash_bank *bank)
                                bank->sectors[i].is_erased = 1;
                }
        } else {
-               LOG_WARNING("kinetis_blank_check not supported yet for 
FlexNVM");
+               LOG_WARNING("kinetis_blank_check not supported yet for 
FlexRAM");
                return ERROR_FLASH_OPERATION_FAILED;
        }
 

-- 

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

Reply via email to