Merge pull request #378 from markrages/nordic_unlock

Add extra port for mass erasing / unprotecting nRF52 with APPROTECT set.
This commit is contained in:
Gareth McMullin 2018-07-28 14:56:03 +12:00 committed by GitHub
commit c5c0783337
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 1 deletions

View File

@ -448,6 +448,9 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
extern void kinetis_mdm_probe(ADIv5_AP_t *);
kinetis_mdm_probe(ap);
extern void nrf51_mdm_probe(ADIv5_AP_t *);
nrf51_mdm_probe(ap);
if (ap->base == 0xffffffff) {
/* No debug entries... useless AP */
adiv5_ap_unref(ap);

View File

@ -341,7 +341,7 @@ const struct command_s kinetis_mdm_cmd_list[] = {
{NULL, NULL, NULL}
};
bool nop_function(void)
static bool nop_function(void)
{
return true;
}

View File

@ -336,3 +336,81 @@ static bool nrf51_cmd_read(target *t, int argc, const char *argv[])
return nrf51_cmd_read_help(t);
}
#include "adiv5.h"
#define NRF52_MDM_IDR 0x02880000
static bool nrf51_mdm_cmd_erase_mass(target *t);
const struct command_s nrf51_mdm_cmd_list[] = {
{"erase_mass", (cmd_handler)nrf51_mdm_cmd_erase_mass, "Erase entire flash memory"},
{NULL, NULL, NULL}
};
static bool nop_function(void)
{
return true;
}
void nrf51_mdm_probe(ADIv5_AP_t *ap)
{
switch(ap->idr) {
case NRF52_MDM_IDR:
break;
default:
return;
}
target *t = target_new();
adiv5_ap_ref(ap);
t->priv = ap;
t->priv_free = (void*)adiv5_ap_unref;
t->driver = "Nordic nRF52 Access Port";
t->attach = (void*)nop_function;
t->detach = (void*)nop_function;
t->check_error = (void*)nop_function;
t->mem_read = (void*)nop_function;
t->mem_write = (void*)nop_function;
t->regs_size = 4;
t->regs_read = (void*)nop_function;
t->regs_write = (void*)nop_function;
t->reset = (void*)nop_function;
t->halt_request = (void*)nop_function;
//t->halt_poll = mdm_halt_poll;
t->halt_resume = (void*)nop_function;
target_add_commands(t, nrf51_mdm_cmd_list, t->driver);
}
#define MDM_POWER_EN ADIV5_DP_REG(0x01)
#define MDM_SELECT_AP ADIV5_DP_REG(0x02)
#define MDM_STATUS ADIV5_AP_REG(0x08)
#define MDM_CONTROL ADIV5_AP_REG(0x04)
#define MDM_PROT_EN ADIV5_AP_REG(0x0C)
static bool nrf51_mdm_cmd_erase_mass(target *t)
{
ADIv5_AP_t *ap = t->priv;
uint32_t status = adiv5_ap_read(ap, MDM_STATUS);
adiv5_dp_write(ap->dp, MDM_POWER_EN, 0x50000000);
adiv5_dp_write(ap->dp, MDM_SELECT_AP, 0x01000000);
adiv5_ap_write(ap, MDM_CONTROL, 0x00000001);
// Read until 0, probably should have a timeout here...
do {
status = adiv5_ap_read(ap, MDM_STATUS);
} while (status);
// The second read will provide true prot status
status = adiv5_ap_read(ap, MDM_PROT_EN);
status = adiv5_ap_read(ap, MDM_PROT_EN);
// should we return the prot status here?
return true;
}