kinetis auto mass erase on secured devices
authorMathias K <kesmtp@freenet.de>
Mon, 12 Sep 2011 19:24:17 +0000 (21:24 +0200)
committerØyvind Harboe <oyvind.harboe@zylin.com>
Fri, 16 Sep 2011 07:51:35 +0000 (09:51 +0200)
This is a proof of concept to get access to the debug port of a
secured kinetis cpu. On full flash erase the cpu is automatically
secured and the debug port is not accessible.
To get this to work the srst line is needed and the necessary
configuration should be added to the configuration file.

src/target/arm_adi_v5.c

index f8a2e2278fc33c000e8ce798f04e4846a1dfe769..21dc54cd3d2ccd7ddf779690ba5b2f857fb08fe6 100644 (file)
@@ -955,6 +955,186 @@ 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)
+                               continue;
+                       if ( 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 +1242,8 @@ int ahbap_debugport_init(struct adiv5_dap *dap)
        if (retval != ERROR_OK)
                return retval;
 
+       dap_syssec(dap);
+
        return ERROR_OK;
 }
 

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)