flash/nor/kinetis: fix FCF handling
[openocd.git] / 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 allow_fcf_writes;
 static uint8_t fcf_fopt = 0xff;
-static bool fcf_fopt_configured;
 static bool create_banks;
 
 
 static bool create_banks;
 
 
@@ -1650,8 +1649,6 @@ static int kinetis_erase(struct flash_bank *bank, unsigned int first,
                        return ERROR_FLASH_OPERATION_FAILED;
                }
 
                        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) {
                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");
                                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;
        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;
        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);
                                         && 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]) {
                        }
                        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;
                        }
                        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
                                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);
 
        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);
        }
        } 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)