stlink: add missing memory check handlers
[openocd.git] / src / target / arm_adi_v5.c
index f8a2e2278fc33c000e8ce798f04e4846a1dfe769..77d01a049d8c678900ffaf14779c65c26eb504ff 100644 (file)
@@ -955,6 +955,184 @@ int mem_ap_sel_write_buf_u32(struct adiv5_dap *swjdp, uint8_t ap,
        return mem_ap_write_buf_u32(swjdp, buffer, count, address);
 }
 
+#define MDM_REG_STAT           0x00
+#define MDM_REG_CTRL           0x04
+#define MDM_REG_ID             0xfc
+
+#define MDM_STAT_FMEACK                (1<<0)
+#define MDM_STAT_FREADY                (1<<1)
+#define MDM_STAT_SYSSEC                (1<<2)
+#define MDM_STAT_SYSRES                (1<<3)
+#define MDM_STAT_FMEEN         (1<<5)
+#define MDM_STAT_BACKDOOREN    (1<<6)
+#define MDM_STAT_LPEN          (1<<7)
+#define MDM_STAT_VLPEN         (1<<8)
+#define MDM_STAT_LLSMODEXIT    (1<<9)
+#define MDM_STAT_VLLSXMODEXIT  (1<<10)
+#define MDM_STAT_CORE_HALTED   (1<<16)
+#define MDM_STAT_CORE_SLEEPDEEP        (1<<17)
+#define MDM_STAT_CORESLEEPING  (1<<18)
+
+#define MEM_CTRL_FMEIP         (1<<0)
+#define MEM_CTRL_DBG_DIS       (1<<1)
+#define MEM_CTRL_DBG_REQ       (1<<2)
+#define MEM_CTRL_SYS_RES_REQ   (1<<3)
+#define MEM_CTRL_CORE_HOLD_RES (1<<4)
+#define MEM_CTRL_VLLSX_DBG_REQ (1<<5)
+#define MEM_CTRL_VLLSX_DBG_ACK (1<<6)
+#define MEM_CTRL_VLLSX_STAT_ACK        (1<<7)
+
+/**
+ *
+ */
+int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap)
+{
+       uint32_t val;
+       int retval;
+       enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+       dap_ap_select(dap, 1);
+
+       /* first check mdm-ap id register */
+       retval = dap_queue_ap_read(dap, MDM_REG_ID, &val);
+       if (retval != ERROR_OK)
+               return retval;
+       dap_run(dap);
+
+       if ( val != 0x001C0000 )
+       {
+               LOG_DEBUG("id doesn't match %08X != 0x001C0000",val);
+               dap_ap_select(dap, 0);
+               return ERROR_FAIL;
+       }
+
+       /* read and parse status register
+        * it's important that the device is out of
+        * reset here
+        */
+       retval = dap_queue_ap_read(dap, MDM_REG_STAT, &val);
+       if (retval != ERROR_OK)
+               return retval;
+       dap_run(dap);
+
+       LOG_DEBUG("MDM_REG_STAT %08X",val);
+
+       if ( (val & (MDM_STAT_SYSSEC|MDM_STAT_FREADY)) != (MDM_STAT_FREADY) )
+       {
+               LOG_DEBUG("MDMAP: system is secured, masserase needed");
+
+               if ( !(val & MDM_STAT_FMEEN) )
+               {
+                       LOG_DEBUG("MDMAP: masserase is disabled");
+               }
+               else
+               {
+                       /* we need to assert reset */
+                       if ( jtag_reset_config & RESET_HAS_SRST )
+                       {
+                               /* default to asserting srst */
+                               if (jtag_reset_config & RESET_SRST_PULLS_TRST)
+                               {
+                                       jtag_add_reset(1, 1);
+                               }
+                               else
+                               {
+                                       jtag_add_reset(0, 1);
+                               }
+                       }
+                       else
+                       {
+                               LOG_DEBUG("SRST not configured");
+                               dap_ap_select(dap, 0);
+                               return ERROR_FAIL;
+                       }
+
+                       while(1)
+                       {
+                               retval = dap_queue_ap_write(dap, MDM_REG_CTRL, MEM_CTRL_FMEIP);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                               dap_run(dap);
+                               /* read status register and wait for ready */
+                               retval = dap_queue_ap_read(dap, MDM_REG_STAT, &val);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                               dap_run(dap);
+                               LOG_DEBUG("MDM_REG_STAT %08X",val);
+
+                               if ( (val&1))
+                                       break;
+                       }
+
+                       while(1)
+                       {
+                               retval = dap_queue_ap_write(dap, MDM_REG_CTRL, 0);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                               dap_run(dap);
+                               /* read status register */
+                               retval = dap_queue_ap_read(dap, MDM_REG_STAT, &val);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                               dap_run(dap);
+                               LOG_DEBUG("MDM_REG_STAT %08X",val);
+                               /* read control register and wait for ready */
+                               retval = dap_queue_ap_read(dap, MDM_REG_CTRL, &val);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                               dap_run(dap);
+                               LOG_DEBUG("MDM_REG_CTRL %08X",val);
+
+                               if ( val == 0x00 )
+                                       break;
+                       }
+               }
+       }
+
+       dap_ap_select(dap, 0);
+
+       return ERROR_OK;
+}
+
+/** */
+struct dap_syssec_filter {
+       /** */
+       uint32_t idcode;
+       /** */
+       int (*dap_init)(struct adiv5_dap *dap);
+};
+
+/** */
+static struct dap_syssec_filter dap_syssec_filter_data[] = {
+       { 0x4BA00477, dap_syssec_kinetis_mdmap }
+};
+
+
+/**
+ *
+ */
+int dap_syssec(struct adiv5_dap *dap)
+{
+       unsigned int i;
+       struct jtag_tap *tap;
+
+       for(i=0;i<sizeof(dap_syssec_filter_data);i++)
+       {
+               tap = dap->jtag_info->tap;
+
+               while (tap != NULL)
+               {
+                       if ( tap->hasidcode && (dap_syssec_filter_data[i].idcode == tap->idcode) )
+                       {
+                               LOG_DEBUG("DAP: mdmap_init for idcode: %08x",tap->idcode);
+                               dap_syssec_filter_data[i].dap_init(dap);
+                       }
+                       tap = tap->next_tap;
+               }
+       }
+
+       return ERROR_OK;
+}
 
 /*--------------------------------------------------------------------------*/
 
@@ -1062,6 +1240,8 @@ int ahbap_debugport_init(struct adiv5_dap *dap)
        if (retval != ERROR_OK)
                return retval;
 
+       dap_syssec(dap);
+
        return ERROR_OK;
 }
 
@@ -1092,7 +1272,7 @@ int dap_get_debugbase(struct adiv5_dap *dap, int ap,
 
        /* AP address is in bits 31:24 of DP_SELECT */
        if (ap >= 256)
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        ap_old = dap->ap_current;
        dap_ap_select(dap, ap);
@@ -1135,7 +1315,7 @@ int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
        int retval = ERROR_FAIL;
 
        if (ap >= 256)
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        ap_old = dap->ap_current;
        dap_ap_select(dap, ap);
@@ -1172,7 +1352,7 @@ static int dap_info_command(struct command_context *cmd_ctx,
                struct adiv5_dap *dap, int ap)
 {
        int retval;
-       uint32_t dbgbase, apid;
+       uint32_t dbgbase = 0, apid = 0; /* Silence gcc by initializing */
        int romtable_present = 0;
        uint8_t mem_ap;
        uint32_t ap_old;
@@ -1619,7 +1799,7 @@ COMMAND_HANDLER(dap_baseaddr_command)
                COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
                /* AP address is in bits 31:24 of DP_SELECT */
                if (apsel >= 256)
-                       return ERROR_INVALID_ARGUMENTS;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
                break;
        default:
                return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1687,7 +1867,7 @@ COMMAND_HANDLER(dap_apsel_command)
                COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
                /* AP address is in bits 31:24 of DP_SELECT */
                if (apsel >= 256)
-                       return ERROR_INVALID_ARGUMENTS;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
                break;
        default:
                return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1726,7 +1906,7 @@ COMMAND_HANDLER(dap_apid_command)
                COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
                /* AP address is in bits 31:24 of DP_SELECT */
                if (apsel >= 256)
-                       return ERROR_INVALID_ARGUMENTS;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
                break;
        default:
                return ERROR_COMMAND_SYNTAX_ERROR;
@@ -1795,6 +1975,7 @@ const struct command_registration dap_command_handlers[] = {
                .name = "dap",
                .mode = COMMAND_EXEC,
                .help = "DAP command group",
+               .usage = "",
                .chain = dap_commands,
        },
        COMMAND_REGISTRATION_DONE

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)