|
|
@@ -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; |
|
|
|
} |
|
|
|
|
|
|
|