flash/nor/kinetis: fix FCF handling 53/5753/3
authorTomas Vanek <vanekt@fbl.cz>
Thu, 2 Jul 2020 08:50:15 +0000 (10:50 +0200)
committerTomas Vanek <vanekt@fbl.cz>
Mon, 13 Jul 2020 18:27:53 +0000 (19:27 +0100)
Kinetis Flash Configuration Field needs special handling to prevent unwanted
locking of the device. Warn user about any difference between generated
FCF and FCF data in the programmed file. Inform user that re-programming
of already programmed FCF may fail on devices with FTFE flash module.

While on it remove useless setting of is_erased flag after erase.

Change-Id: I3911f436674547fa12ef3886c7d5e8cd889f9e2b
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Fixes: https://sourceforge.net/p/openocd/tickets/270/
Reported-by: Noel Diviney <vk3avm@users.sourceforge.net>
Reviewed-on: http://openocd.zylin.com/5753
Tested-by: jenkins
src/flash/nor/kinetis.c

index d89747804edbe6107ae3fbbb5bfa6857b1c973db..07c5eac36850fe025a36df366e4bc6603a1c0288 100644 (file)
@@ -389,7 +389,6 @@ static const struct kinetis_type kinetis_types_old[] = {
 
 static bool allow_fcf_writes;
 static uint8_t fcf_fopt = 0xff;
-static bool fcf_fopt_configured;
 static bool create_banks;
 
 
@@ -1650,8 +1649,6 @@ static int kinetis_erase(struct flash_bank *bank, unsigned int first,
                        return ERROR_FLASH_OPERATION_FAILED;
                }
 
-               bank->sectors[i].is_erased = 1;
-
                if (k_bank->prog_base == 0
                        && bank->sectors[i].offset <= FCF_ADDRESS
                        && bank->sectors[i].offset + bank->sectors[i].size > FCF_ADDRESS + FCF_SIZE) {
@@ -1665,7 +1662,8 @@ static int kinetis_erase(struct flash_bank *bank, unsigned int first,
                                result = kinetis_write_inner(bank, fcf_buffer, FCF_ADDRESS, FCF_SIZE);
                                if (result != ERROR_OK)
                                        LOG_WARNING("Flash Configuration Field write failed");
-                               bank->sectors[i].is_erased = 0;
+                               else
+                                       LOG_DEBUG("Generated FCF written");
                        }
                }
        }
@@ -1909,6 +1907,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
        int result;
        bool set_fcf = false;
        bool fcf_in_data_valid = false;
+       bool fcf_differs = false;
        int sect = 0;
        struct kinetis_flash_bank *k_bank = bank->driver_priv;
        struct kinetis_chip *k_chip = k_bank->k_chip;
@@ -1941,31 +1940,45 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
                                         && offset + count >= FCF_ADDRESS + FCF_SIZE;
                if (fcf_in_data_valid) {
                        memcpy(fcf_in_data, buffer + FCF_ADDRESS - offset, FCF_SIZE);
-                       if (memcmp(fcf_in_data + FCF_FPROT, fcf_buffer, 4)) {
-                               fcf_in_data_valid = false;
-                               LOG_INFO("Flash protection requested in programmed file differs from current setting.");
+                       if (memcmp(fcf_in_data, fcf_buffer, 8)) {
+                               fcf_differs = true;
+                               LOG_INFO("Setting of backdoor key is not supported in mode 'kinetis fcf_source protection'.");
+                       }
+                       if (memcmp(fcf_in_data + FCF_FPROT, fcf_buffer + FCF_FPROT, 4)) {
+                               fcf_differs = true;
+                               LOG_INFO("Flash protection requested in the programmed file differs from current setting.");
                        }
                        if (fcf_in_data[FCF_FDPROT] != fcf_buffer[FCF_FDPROT]) {
-                               fcf_in_data_valid = false;
-                               LOG_INFO("Data flash protection requested in programmed file differs from current setting.");
+                               fcf_differs = true;
+                               LOG_INFO("Data flash protection requested in the programmed file differs from current setting.");
                        }
                        if ((fcf_in_data[FCF_FSEC] & 3) != 2) {
                                fcf_in_data_valid = false;
-                               LOG_INFO("Device security requested in programmed file!");
-                       } else if (k_chip->flash_support & FS_ECC
-                           && fcf_in_data[FCF_FSEC] != fcf_buffer[FCF_FSEC]) {
-                               fcf_in_data_valid = false;
+                               LOG_INFO("Device security requested in the programmed file! Write denied.");
+                       } else if (fcf_in_data[FCF_FSEC] != fcf_buffer[FCF_FSEC]) {
+                               fcf_differs = true;
                                LOG_INFO("Strange unsecure mode 0x%02" PRIx8
-                                        "requested in programmed file!",
-                                        fcf_in_data[FCF_FSEC]);
+                                       " requested in the programmed file, set FSEC = 0x%02" PRIx8
+                                       " in the startup code!",
+                                       fcf_in_data[FCF_FSEC], fcf_buffer[FCF_FSEC]);
                        }
-                       if ((k_chip->flash_support & FS_ECC || fcf_fopt_configured)
-                           && fcf_in_data[FCF_FOPT] != fcf_fopt) {
-                               fcf_in_data_valid = false;
-                               LOG_INFO("FOPT requested in programmed file differs from current setting.");
+                       if (fcf_in_data[FCF_FOPT] != fcf_buffer[FCF_FOPT]) {
+                               fcf_differs = true;
+                               LOG_INFO("FOPT requested in the programmed file differs from current setting, set 'kinetis fopt 0x%02"
+                                       PRIx8 "'.", fcf_in_data[FCF_FOPT]);
+                       }
+
+                       /* If the device has ECC flash, then we cannot re-program FCF */
+                       if (fcf_differs) {
+                               if (k_chip->flash_support & FS_ECC) {
+                                       fcf_in_data_valid = false;
+                                       LOG_INFO("Cannot re-program FCF. Expect verify errors at FCF (0x400-0x40f).");
+                               } else {
+                                       LOG_INFO("Trying to re-program FCF.");
+                                       if (!(k_chip->flash_support & FS_PROGRAM_LONGWORD))
+                                               LOG_INFO("Flash re-programming may fail on this device!");
+                               }
                        }
-                       if (!fcf_in_data_valid)
-                               LOG_INFO("Expect verify errors at FCF (0x408-0x40f).");
                }
        }
 
@@ -3035,7 +3048,6 @@ COMMAND_HANDLER(kinetis_fopt_handler)
 
        if (CMD_ARGC == 1) {
                fcf_fopt = (uint8_t)strtoul(CMD_ARGV[0], NULL, 0);
-               fcf_fopt_configured = true;
        } else {
                command_print(CMD, "FCF_FOPT 0x%02" PRIx8, fcf_fopt);
        }

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)