Exemple #1
0
int lmi_flash_erase(struct target_s *target, uint32_t addr, int len)
{
	ADIv5_AP_t *ap = adiv5_target_ap(target);
	uint32_t tmp;

	addr &= 0xFFFFFC00;
	len &= 0xFFFFFC00;

	/* setup word access */
	adiv5_ap_write(ap, 0x00, 0xA2000052);

	/* select Flash Control */
	adiv5_dp_low_access(ap->dp, 1, 0, 0x04, 0x400FD000);

	while(len) {
		/* write address to FMA */
		adiv5_ap_write(ap, 0x10, addr); /* Required to switch banks */
		/* set ERASE bit in FMC */
		adiv5_dp_low_access(ap->dp, 1, 0, 0x08, 0xA4420002);
		/* Read FMC to poll for ERASE bit */
		adiv5_dp_low_access(ap->dp, 1, 1, 0x08, 0);
		do {
			tmp = adiv5_dp_low_access(ap->dp, 1, 1, 0x08, 0);
		} while (tmp & 2);

		len -= 0x400;
		addr += 0x400;
	}
	return 0;
}
static void apb_write(target *t, uint16_t reg, uint32_t val)
{
	struct cortexa_priv *priv = t->priv;
	ADIv5_AP_t *ap = priv->apb;
	uint32_t addr = priv->base + 4*reg;
	adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
	adiv5_dp_low_access(ap->dp, ADIV5_LOW_WRITE, ADIV5_AP_DRW, val);
}
static uint32_t apb_read(target *t, uint16_t reg)
{
	struct cortexa_priv *priv = t->priv;
	ADIv5_AP_t *ap = priv->apb;
	uint32_t addr = priv->base + 4*reg;
	adiv5_ap_write(ap, ADIV5_AP_TAR, addr);
	adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ, ADIV5_AP_DRW, 0);
	return adiv5_dp_low_access(ap->dp, ADIV5_LOW_READ, ADIV5_DP_RDBUFF, 0);
}
bool cortexa_probe(ADIv5_AP_t *apb, uint32_t debug_base)
{
	target *t;

	t = target_new();
	adiv5_ap_ref(apb);
	struct cortexa_priv *priv = calloc(1, sizeof(*priv));
	t->priv = priv;
	t->priv_free = free;
	priv->apb = apb;
	/* FIXME Find a better way to find the AHB.  This is likely to be
	 * device specific. */
	priv->ahb = adiv5_new_ap(apb->dp, 0);
	adiv5_ap_ref(priv->ahb);
	if ((priv->ahb->idr & 0xfffe00f) == 0x4770001) {
		/* This is an AHB */
		t->mem_read = cortexa_mem_read;
		t->mem_write = cortexa_mem_write;
	} else {
		/* This is not an AHB, fall back to slow APB access */
		adiv5_ap_unref(priv->ahb);
		priv->ahb = NULL;
		t->mem_read = cortexa_slow_mem_read;
		t->mem_write = cortexa_slow_mem_write;
	}

	priv->base = debug_base;
	/* Set up APB CSW, we won't touch this again */
	uint32_t csw = apb->csw | ADIV5_AP_CSW_SIZE_WORD;
	adiv5_ap_write(apb, ADIV5_AP_CSW, csw);
	uint32_t dbgdidr = apb_read(t, DBGDIDR);
	priv->hw_breakpoint_max = ((dbgdidr >> 24) & 15)+1;

	t->check_error = cortexa_check_error;

	t->driver = cortexa_driver_str;

	t->attach = cortexa_attach;
	t->detach = cortexa_detach;

	t->tdesc = tdesc_cortex_a;
	t->regs_read = cortexa_regs_read;
	t->regs_write = cortexa_regs_write;

	t->reset = cortexa_reset;
	t->halt_request = cortexa_halt_request;
	t->halt_poll = cortexa_halt_poll;
	t->halt_resume = cortexa_halt_resume;
	t->regs_size = sizeof(priv->reg_cache);

	t->breakwatch_set = cortexa_breakwatch_set;
	t->breakwatch_clear = cortexa_breakwatch_clear;

	return true;
}
Exemple #5
0
static bool kinetis_mdm_cmd_erase_mass(target *t)
{
	ADIv5_AP_t *ap = t->priv;

	uint32_t status, control;
	status = adiv5_ap_read(ap, MDM_STATUS);
	control = adiv5_ap_read(ap, MDM_CONTROL);
	tc_printf(t, "Requesting mass erase (status = 0x%"PRIx32")\n", status);

	if (!(status & MDM_STATUS_MASS_ERASE_ENABLED)) {
		tc_printf(t, "ERROR: Mass erase disabled!\n");
		return false;
	}

	if (!(status & MDM_STATUS_FLASH_READY)) {
		tc_printf(t, "ERROR: Flash not ready!\n");
		return false;
	}

	if (status & MDM_STATUS_MASS_ERASE_ACK) {
		tc_printf(t, "ERROR: Mass erase already in progress!\n");
		return false;
	}

	adiv5_ap_write(ap, MDM_CONTROL, MDM_CONTROL_MASS_ERASE);

	do {
		status = adiv5_ap_read(ap, MDM_STATUS);
	} while (!(status & MDM_STATUS_MASS_ERASE_ACK));
	tc_printf(t, "Mass erase acknowledged\n");

	do {
		control = adiv5_ap_read(ap, MDM_CONTROL);
	} while (!(control & MDM_CONTROL_MASS_ERASE));
	tc_printf(t, "Mass erase complete\n");

	return true;
}