Beispiel #1
0
static int aduc702x_erase(struct flash_bank *bank, int first, int last)
{
        //int res;
	int x;
	int count;
	//uint32_t v;
	struct target *target = bank->target;

        aduc702x_set_write_enable(target, 1);

	/* mass erase */
	if (((first | last) == 0) || ((first == 0) && (last >= bank->num_sectors))) {
		LOG_DEBUG("performing mass erase.\n");
		target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEDAT, 0x3cff);
		target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEADR, 0xffc3);
		target_write_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEECON, 0x06);

                if (aduc702x_check_flash_completion(target, 3500) != ERROR_OK)
		{
			LOG_ERROR("mass erase failed\n");
                        aduc702x_set_write_enable(target, 0);
			return ERROR_FLASH_OPERATION_FAILED;
		}

		LOG_DEBUG("mass erase successful.\n");
		return ERROR_OK;
	} else {
                unsigned long adr;

                count = last - first + 1;
                for (x = 0; x < count; ++x)
                {
                        adr = bank->base + ((first + x) * 512);

                        target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEADR, adr);
                        target_write_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEECON, 0x05);

                        if (aduc702x_check_flash_completion(target, 50) != ERROR_OK)
                        {
                                LOG_ERROR("failed to erase sector at address 0x%08lX\n", adr);
                                aduc702x_set_write_enable(target, 0);
                                return ERROR_FLASH_SECTOR_NOT_ERASED;
                        }

                        LOG_DEBUG("erased sector at address 0x%08lX\n", adr);
                }
        }

        aduc702x_set_write_enable(target, 0);

	return ERROR_OK;
}
Beispiel #2
0
/* sets FEEMOD bit 3
 * enable = 1 enables writes & erases, 0 disables them */
static int aduc702x_set_write_enable(struct target *target, int enable)
{
	/* don't bother to preserve int enable bit here */
	target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEMOD, enable ? 8 : 0);

	return ERROR_OK;
}
/* write a word (16bit) from the pc to the netx */
int fn_write_data16(void *pvHandle, unsigned long ulNetxAddress, unsigned short usData)
{
	command_context_t *cmd_ctx;
	target_t *target;
	int iResult;


	/* cast the handle to the command context */
	cmd_ctx = (command_context_t*)pvHandle;

	/* get the target from the command context */
	target = get_current_target(cmd_ctx);

	/* read the data from the netX */
	iResult = target_write_u16(target, ulNetxAddress, usData);
	if( iResult==ERROR_OK )
	{
		iResult = 0;
	}
	else
	{
		iResult = 1;
	}

	wxMilliSleep(1);

	return iResult;
}
Beispiel #4
0
/** Checks whether a memory region is zeroed. */
int armv7m_blank_check_memory(struct target *target,
		uint32_t address, uint32_t count, uint32_t* blank)
{
	struct working_area *erase_check_algorithm;
	struct reg_param reg_params[3];
	struct armv7m_algorithm armv7m_info;
	int retval;
	uint32_t i;

	static const uint16_t erase_check_code[] =
	{
		/* loop: */
		0xF810, 0x3B01,		/* ldrb r3, [r0], #1 */
		0xEA02, 0x0203,		/* and  r2, r2, r3 */
		0x3901,				/* subs	r1, r1, #1 */
		0xD1F9,				/* bne	loop */
		0xBE00,     		/* bkpt #0 */
	};

	/* make sure we have a working area */
	if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
	{
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
	}

	/* convert flash writing code into a buffer in target endianness */
	for (i = 0; i < ARRAY_SIZE(erase_check_code); i++)
		target_write_u16(target, erase_check_algorithm->address + i*sizeof(uint16_t), erase_check_code[i]);

	armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
	armv7m_info.core_mode = ARMV7M_MODE_ANY;

	init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
	buf_set_u32(reg_params[0].value, 0, 32, address);

	init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
	buf_set_u32(reg_params[1].value, 0, 32, count);

	init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
	buf_set_u32(reg_params[2].value, 0, 32, 0xff);

	retval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address,
	                              erase_check_algorithm->address + (sizeof(erase_check_code) - 2),
	                              10000, &armv7m_info);

	if (retval == ERROR_OK)
		*blank = buf_get_u32(reg_params[2].value, 0, 32);

	destroy_reg_param(&reg_params[0]);
	destroy_reg_param(&reg_params[1]);
	destroy_reg_param(&reg_params[2]);

	target_free_working_area(target, erase_check_algorithm);

	return retval;
}
Beispiel #5
0
/* All-JTAG, single-access method.  Very slow.  Used only if there is no
 * working area available. */
static int aduc702x_write_single(struct flash_bank *bank,
	const uint8_t *buffer,
	uint32_t offset,
	uint32_t count)
{
	uint32_t x;
	uint8_t b;
	struct target *target = bank->target;

	aduc702x_set_write_enable(target, 1);

	for (x = 0; x < count; x += 2) {
		/* FEEADR = address */
		target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEADR, offset + x);

		/* set up data */
		if ((x + 1) == count) {
			/* last byte */
			target_read_u8(target, offset + x + 1, &b);
		} else
			b = buffer[x + 1];

		target_write_u16(target, ADUC702x_FLASH + ADUC702x_FLASH_FEEDAT, buffer[x] | (b << 8));

		/* do single-write command */
		target_write_u8(target, ADUC702x_FLASH + ADUC702x_FLASH_FEECON, 0x02);

		if (aduc702x_check_flash_completion(target, 1) != ERROR_OK) {
			LOG_ERROR("single write failed for address 0x%08lX",
				(unsigned long)(offset + x));
			aduc702x_set_write_enable(target, 0);
			return ERROR_FLASH_OPERATION_FAILED;
		}

	}
	LOG_DEBUG("wrote %d bytes at address 0x%08lX", (int)count, (unsigned long)(offset + x));

	aduc702x_set_write_enable(target, 0);

	return ERROR_OK;
}
Beispiel #6
0
int s3c24xx_address(struct nand_device *nand, uint8_t address)
{
	struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
	struct target *target = nand->target;

	if (target->state != TARGET_HALTED) {
		LOG_ERROR("target must be halted to use S3C24XX NAND flash controller");
		return ERROR_NAND_OPERATION_FAILED;
	}

	target_write_u16(target, s3c24xx_info->addr, address);
	return ERROR_OK;
}
Beispiel #7
0
static int str9x_protect(struct flash_bank *bank,
		int set, int first, int last)
{
	struct target *target = bank->target;
	int i;
	uint32_t adr;
	uint8_t status;

	if (bank->target->state != TARGET_HALTED)
	{
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	for (i = first; i <= last; i++)
	{
		/* Level One Protection */

		adr = bank->base + bank->sectors[i].offset;

		target_write_u16(target, adr, 0x60);
		if (set)
			target_write_u16(target, adr, 0x01);
		else
			target_write_u16(target, adr, 0xD0);

		/* query status */
		target_read_u8(target, adr, &status);

		/* clear status, also clear read array */
		target_write_u16(target, adr, 0x50);

		/* read array command */
		target_write_u16(target, adr, 0xFF);
	}

	return ERROR_OK;
}
Beispiel #8
0
static int str9x_protect_check(struct flash_bank *bank)
{
	int retval;
	struct str9x_flash_bank *str9x_info = bank->driver_priv;
	struct target *target = bank->target;

	int i;
	uint32_t adr;
	uint32_t status = 0;
	uint16_t hstatus = 0;

	if (bank->target->state != TARGET_HALTED) {
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	/* read level one protection */

	if (str9x_info->variant) {
		if (str9x_info->bank1) {
			adr = bank1start + 0x18;
			retval = target_write_u16(target, adr, 0x90);
			if (retval != ERROR_OK)
				return retval;
			retval = target_read_u16(target, adr, &hstatus);
			if (retval != ERROR_OK)
				return retval;
			status = hstatus;
		} else {
			adr = bank1start + 0x14;
			retval = target_write_u16(target, adr, 0x90);
			if (retval != ERROR_OK)
				return retval;
			retval = target_read_u32(target, adr, &status);
			if (retval != ERROR_OK)
				return retval;
		}
	} else {
		adr = bank1start + 0x10;
		retval = target_write_u16(target, adr, 0x90);
		if (retval != ERROR_OK)
			return retval;
		retval = target_read_u16(target, adr, &hstatus);
		if (retval != ERROR_OK)
			return retval;
		status = hstatus;
	}

	/* read array command */
	retval = target_write_u16(target, adr, 0xFF);
	if (retval != ERROR_OK)
		return retval;

	for (i = 0; i < bank->num_sectors; i++) {
		if (status & str9x_info->sector_bits[i])
			bank->sectors[i].is_protected = 1;
		else
			bank->sectors[i].is_protected = 0;
	}

	return ERROR_OK;
}
Beispiel #9
0
static int stm32x_write(struct flash_bank *bank, uint8_t *buffer,
		uint32_t offset, uint32_t count)
{
	struct target *target = bank->target;
	uint32_t words_remaining = (count / 2);
	uint32_t bytes_remaining = (count & 0x00000001);
	uint32_t address = bank->base + offset;
	uint32_t bytes_written = 0;
	int retval;

	if (bank->target->state != TARGET_HALTED)
	{
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	if (offset & 0x1)
	{
		LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
		return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
	}

	/* unlock flash registers */
	retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY1);
	if (retval != ERROR_OK)
		return retval;
	retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY2);
	if (retval != ERROR_OK)
		return retval;

	/* multiple half words (2-byte) to be programmed? */
	if (words_remaining > 0)
	{
		/* try using a block write */
		if ((retval = stm32x_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
		{
			if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
			{
				/* if block write failed (no sufficient working area),
				 * we use normal (slow) single dword accesses */
				LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
			}
		}
		else
		{
			buffer += words_remaining * 2;
			address += words_remaining * 2;
			words_remaining = 0;
		}
	}

	if ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))
		return retval;

	while (words_remaining > 0)
	{
		uint16_t value;
		memcpy(&value, buffer + bytes_written, sizeof(uint16_t));

		retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_PG);
		if (retval != ERROR_OK)
			return retval;
		retval = target_write_u16(target, address, value);
		if (retval != ERROR_OK)
			return retval;

		retval = stm32x_wait_status_busy(bank, 5);
		if (retval != ERROR_OK)
			return retval;

		bytes_written += 2;
		words_remaining--;
		address += 2;
	}

	if (bytes_remaining)
	{
		uint16_t value = 0xffff;
		memcpy(&value, buffer + bytes_written, bytes_remaining);

		retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_PG);
		if (retval != ERROR_OK)
			return retval;
		retval = target_write_u16(target, address, value);
		if (retval != ERROR_OK)
			return retval;

		retval = stm32x_wait_status_busy(bank, 5);
		if (retval != ERROR_OK)
			return retval;
	}

	return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
}
Beispiel #10
0
static int stm32x_write_options(struct flash_bank *bank)
{
	struct stm32x_flash_bank *stm32x_info = NULL;
	struct target *target = bank->target;

	stm32x_info = bank->driver_priv;

	/* unlock flash registers */
	int retval = target_write_u32(target, STM32_FLASH_KEYR, KEY1);
	if (retval != ERROR_OK)
		return retval;
	retval = target_write_u32(target, STM32_FLASH_KEYR, KEY2);
	if (retval != ERROR_OK)
		return retval;

	/* unlock option flash registers */
	retval = target_write_u32(target, STM32_FLASH_OPTKEYR, KEY1);
	if (retval != ERROR_OK)
		return retval;
	retval = target_write_u32(target, STM32_FLASH_OPTKEYR, KEY2);
	if (retval != ERROR_OK)
		return retval;

	/* program option bytes */
	retval = target_write_u32(target, STM32_FLASH_CR, FLASH_OPTPG | FLASH_OPTWRE);
	if (retval != ERROR_OK)
		return retval;

	/* write user option byte */
	retval = target_write_u16(target, STM32_OB_USER, stm32x_info->option_bytes.user_options);
	if (retval != ERROR_OK)
		return retval;

	retval = stm32x_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	/* write protection byte 1 */
	retval = target_write_u16(target, STM32_OB_WRP0, stm32x_info->option_bytes.protection[0]);
	if (retval != ERROR_OK)
		return retval;

	retval = stm32x_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	/* write protection byte 2 */
	retval = target_write_u16(target, STM32_OB_WRP1, stm32x_info->option_bytes.protection[1]);
	if (retval != ERROR_OK)
		return retval;

	retval = stm32x_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	/* write protection byte 3 */
	retval = target_write_u16(target, STM32_OB_WRP2, stm32x_info->option_bytes.protection[2]);
	if (retval != ERROR_OK)
		return retval;

	retval = stm32x_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	/* write protection byte 4 */
	retval = target_write_u16(target, STM32_OB_WRP3, stm32x_info->option_bytes.protection[3]);
	if (retval != ERROR_OK)
		return retval;

	retval = stm32x_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	/* write readout protection bit */
	retval = target_write_u16(target, STM32_OB_RDP, stm32x_info->option_bytes.RDP);
	if (retval != ERROR_OK)
		return retval;

	retval = stm32x_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	retval = target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
	if (retval != ERROR_OK)
		return retval;

	return ERROR_OK;
}
Beispiel #11
0
static int em357_write_options(struct flash_bank *bank)
{
	struct em357_flash_bank *em357_info = NULL;
	struct target *target = bank->target;

	em357_info = bank->driver_priv;

	/* unlock flash registers */
	int retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);
	if (retval != ERROR_OK)
		return retval;
	retval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);
	if (retval != ERROR_OK)
		return retval;

	/* unlock option flash registers */
	retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY1);
	if (retval != ERROR_OK)
		return retval;
	retval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY2);
	if (retval != ERROR_OK)
		return retval;

	/* program option bytes */
	retval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTPG | FLASH_OPTWRE);
	if (retval != ERROR_OK)
		return retval;

	retval = em357_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	/* write protection byte 1 */
	retval = target_write_u16(target, EM357_OB_WRP0, em357_info->option_bytes.protection[0]);
	if (retval != ERROR_OK)
		return retval;

	retval = em357_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	/* write protection byte 2 */
	retval = target_write_u16(target, EM357_OB_WRP1, em357_info->option_bytes.protection[1]);
	if (retval != ERROR_OK)
		return retval;

	retval = em357_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	/* write protection byte 3 */
	retval = target_write_u16(target, EM357_OB_WRP2, em357_info->option_bytes.protection[2]);
	if (retval != ERROR_OK)
		return retval;

	retval = em357_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	/* write readout protection bit */
	retval = target_write_u16(target, EM357_OB_RDP, em357_info->option_bytes.RDP);
	if (retval != ERROR_OK)
		return retval;

	retval = em357_wait_status_busy(bank, 10);
	if (retval != ERROR_OK)
		return retval;

	retval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK);
	if (retval != ERROR_OK)
		return retval;

	return ERROR_OK;
}
Beispiel #12
0
static int fm3_erase(struct flash_bank *bank, int first, int last)
{
	struct fm3_flash_bank *fm3_info = bank->driver_priv;
	struct target *target = bank->target;
	int retval = ERROR_OK;
	uint32_t u32DummyRead;
	int sector, odd;
	uint32_t u32FlashType;
	uint32_t u32FlashSeqAddress1;
	uint32_t u32FlashSeqAddress2;

	u32FlashType = (uint32_t) fm3_info->flashtype;

	if (u32FlashType == fm3_flash_type1)
	{
		u32FlashSeqAddress1 = 0x00001550;
		u32FlashSeqAddress2 = 0x00000AA8;
	}
	else if (u32FlashType == fm3_flash_type2)
	{
		u32FlashSeqAddress1 = 0x00000AA8;
		u32FlashSeqAddress2 = 0x00000554;
	}
	else
	{
		LOG_ERROR("Flash/Device type unknown!");
		return ERROR_FLASH_OPERATION_FAILED;
	}

	if (target->state != TARGET_HALTED) {
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	LOG_INFO("Fujitsu MB9Bxxx: Sector Erase ... (%d to %d)", first, last);

	/* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash acccess) */
	retval = target_write_u32(target, 0x40000000, 0x0001);
	if (retval != ERROR_OK)
		return retval;

	/* dummy read of FASZR */
	retval = target_read_u32(target, 0x40000000, &u32DummyRead);
	if (retval != ERROR_OK)
		return retval;

	for (sector = first ; sector <= last ; sector++)
	{
		uint32_t offset = bank->sectors[sector].offset;

		for (odd = 0; odd < 2 ; odd++)
		{
			if (odd)
				offset += 4;

			/* Flash unlock sequence */
			retval = target_write_u16(target, u32FlashSeqAddress1, 0x00AA);
			if (retval != ERROR_OK)
				return retval;

			retval = target_write_u16(target, u32FlashSeqAddress2, 0x0055);
			if (retval != ERROR_OK)
				return retval;

			retval = target_write_u16(target, u32FlashSeqAddress1, 0x0080);
			if (retval != ERROR_OK)
				return retval;

			retval = target_write_u16(target, u32FlashSeqAddress1, 0x00AA);
			if (retval != ERROR_OK)
				return retval;

			retval = target_write_u16(target, u32FlashSeqAddress2, 0x0055);
			if (retval != ERROR_OK)
				return retval;

			/* Sector erase command (0x0030) */
			retval = target_write_u16(target, offset, 0x0030);
			if (retval != ERROR_OK)
				return retval;

			retval = fm3_busy_wait(target, offset, 500);
			if (retval != ERROR_OK)
				return retval;
		}
		bank->sectors[sector].is_erased = 1;
	}

	/* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash acccess) */
	retval = target_write_u32(target, 0x40000000, 0x0002);
	if (retval != ERROR_OK)
		return retval;

	/* dummy read of FASZR */
	retval = target_read_u32(target, 0x40000000, &u32DummyRead);

	return retval;
}
Beispiel #13
0
/* Chip erase */
static int fm3_chip_erase(struct flash_bank *bank)
{
	struct target *target = bank->target;
	struct fm3_flash_bank *fm3_info2 = bank->driver_priv;
	int retval = ERROR_OK;
	uint32_t u32DummyRead;
	uint32_t u32FlashType;
	uint32_t u32FlashSeqAddress1;
	uint32_t u32FlashSeqAddress2;

	u32FlashType = (uint32_t) fm3_info2->flashtype;

	if (u32FlashType == fm3_flash_type1) {
		LOG_INFO("*** Erasing mb9bfxxx type");
		u32FlashSeqAddress1 = 0x00001550;
		u32FlashSeqAddress2 = 0x00000AA8;
	} else if (u32FlashType == fm3_flash_type2) {
		LOG_INFO("*** Erasing mb9afxxx type");
		u32FlashSeqAddress1 = 0x00000AA8;
		u32FlashSeqAddress2 = 0x00000554;
	} else {
		LOG_ERROR("Flash/Device type unknown!");
		return ERROR_FLASH_OPERATION_FAILED;
	}

	if (target->state != TARGET_HALTED) {
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	LOG_INFO("Fujitsu MB9[AB]xxx: Chip Erase ... (may take several seconds)");

	/* Implement Flash chip erase (mass erase) completely on host */

	/* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */
	retval = target_write_u32(target, 0x40000000, 0x0001);
	if (retval != ERROR_OK)
		return retval;

	/* dummy read of FASZR */
	retval = target_read_u32(target, 0x40000000, &u32DummyRead);
	if (retval != ERROR_OK)
		return retval;

	/* Flash unlock sequence */
	retval = target_write_u16(target, u32FlashSeqAddress1, 0x00AA);
	if (retval != ERROR_OK)
		return retval;

	retval = target_write_u16(target, u32FlashSeqAddress2, 0x0055);
	if (retval != ERROR_OK)
		return retval;

	retval = target_write_u16(target, u32FlashSeqAddress1, 0x0080);
	if (retval != ERROR_OK)
		return retval;

	retval = target_write_u16(target, u32FlashSeqAddress1, 0x00AA);
	if (retval != ERROR_OK)
		return retval;

	retval = target_write_u16(target, u32FlashSeqAddress2, 0x0055);
	if (retval != ERROR_OK)
		return retval;

	/* Chip Erase command (0x0010) */
	retval = target_write_u16(target, u32FlashSeqAddress1, 0x0010);
	if (retval != ERROR_OK)
		return retval;

	retval = fm3_busy_wait(target, u32FlashSeqAddress2, 20000);	/* 20s timeout */
	if (retval != ERROR_OK)
		return retval;

	/* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */
	retval = target_write_u32(target, 0x40000000, 0x0002);
	if (retval != ERROR_OK)
		return retval;

	retval = target_read_u32(target, 0x40000000, &u32DummyRead); /* dummy read of FASZR */

	return retval;
}
Beispiel #14
0
static int str9x_erase(struct flash_bank *bank, int first, int last)
{
	struct target *target = bank->target;
	int i;
	uint32_t adr;
	uint8_t status;
	uint8_t erase_cmd;

	if (bank->target->state != TARGET_HALTED)
	{
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	/*A slower but stable way of erasing*/
	/* Erase sector command */
	erase_cmd = 0x20;

	for (i = first; i <= last; i++)
	{
		int retval;
		adr = bank->base + bank->sectors[i].offset;

		/* erase sectors */
		if ((retval = target_write_u16(target, adr, erase_cmd)) != ERROR_OK)
		{
			return retval;
		}
		if ((retval = target_write_u16(target, adr, 0xD0)) != ERROR_OK)
		{
			return retval;
		}

		/* get status */
		if ((retval = target_write_u16(target, adr, 0x70)) != ERROR_OK)
		{
			return retval;
		}

		int timeout;
		for (timeout = 0; timeout < 1000; timeout++) {
			if ((retval = target_read_u8(target, adr, &status)) != ERROR_OK)
			{
				return retval;
			}
			if (status & 0x80)
				break;
			alive_sleep(1);
		}
		if (timeout == 1000)
		{
			LOG_ERROR("erase timed out");
			return ERROR_FAIL;
		}

		/* clear status, also clear read array */
		if ((retval = target_write_u16(target, adr, 0x50)) != ERROR_OK)
		{
			return retval;
		}

		/* read array command */
		if ((retval = target_write_u16(target, adr, 0xFF)) != ERROR_OK)
		{
			return retval;
		}

		if (status & 0x22)
		{
			LOG_ERROR("error erasing flash bank, status: 0x%x", status);
			return ERROR_FLASH_OPERATION_FAILED;
		}
	}

	for (i = first; i <= last; i++)
		bank->sectors[i].is_erased = 1;

	return ERROR_OK;
}
Beispiel #15
0
static int str9x_erase(struct flash_bank *bank, int first, int last)
{
	struct target *target = bank->target;
	int i;
	uint32_t adr;
	uint8_t status;
	uint8_t erase_cmd;
	int total_timeout;

	if (bank->target->state != TARGET_HALTED) {
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	/* Check if we can erase whole bank */
	if ((first == 0) && (last == (bank->num_sectors - 1))) {
		/* Optimize to run erase bank command instead of sector */
		erase_cmd = 0x80;
		/* Add timeout duration since erase bank takes more time */
		total_timeout = 1000 * bank->num_sectors;
	} else {
		/* Erase sector command */
		erase_cmd = 0x20;
		total_timeout = 1000;
	}

	/* this is so the compiler can *know* */
	assert(total_timeout > 0);

	for (i = first; i <= last; i++) {
		int retval;
		adr = bank->base + bank->sectors[i].offset;

		/* erase sectors or block */
		retval = target_write_u16(target, adr, erase_cmd);
		if (retval != ERROR_OK)
			return retval;
		retval = target_write_u16(target, adr, 0xD0);
		if (retval != ERROR_OK)
			return retval;

		/* get status */
		retval = target_write_u16(target, adr, 0x70);
		if (retval != ERROR_OK)
			return retval;

		int timeout;
		for (timeout = 0; timeout < total_timeout; timeout++) {
			retval = target_read_u8(target, adr, &status);
			if (retval != ERROR_OK)
				return retval;
			if (status & 0x80)
				break;
			alive_sleep(1);
		}
		if (timeout == total_timeout) {
			LOG_ERROR("erase timed out");
			return ERROR_FAIL;
		}

		/* clear status, also clear read array */
		retval = target_write_u16(target, adr, 0x50);
		if (retval != ERROR_OK)
			return retval;

		/* read array command */
		retval = target_write_u16(target, adr, 0xFF);
		if (retval != ERROR_OK)
			return retval;

		if (status & 0x22) {
			LOG_ERROR("error erasing flash bank, status: 0x%x", status);
			return ERROR_FLASH_OPERATION_FAILED;
		}

		/* If we ran erase bank command, we are finished */
		if (erase_cmd == 0x80)
			break;
	}

	for (i = first; i <= last; i++)
		bank->sectors[i].is_erased = 1;

	return ERROR_OK;
}
Beispiel #16
0
static int str9x_write(struct flash_bank *bank,
		const uint8_t *buffer, uint32_t offset, uint32_t count)
{
	struct target *target = bank->target;
	uint32_t words_remaining = (count / 2);
	uint32_t bytes_remaining = (count & 0x00000001);
	uint32_t address = bank->base + offset;
	uint32_t bytes_written = 0;
	uint8_t status;
	int retval;
	uint32_t check_address = offset;
	uint32_t bank_adr;
	int i;

	if (bank->target->state != TARGET_HALTED) {
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}

	if (offset & 0x1) {
		LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
		return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
	}

	for (i = 0; i < bank->num_sectors; i++) {
		uint32_t sec_start = bank->sectors[i].offset;
		uint32_t sec_end = sec_start + bank->sectors[i].size;

		/* check if destination falls within the current sector */
		if ((check_address >= sec_start) && (check_address < sec_end)) {
			/* check if destination ends in the current sector */
			if (offset + count < sec_end)
				check_address = offset + count;
			else
				check_address = sec_end;
		}
	}

	if (check_address != offset + count)
		return ERROR_FLASH_DST_OUT_OF_BANK;

	/* multiple half words (2-byte) to be programmed? */
	if (words_remaining > 0) {
		/* try using a block write */
		retval = str9x_write_block(bank, buffer, offset, words_remaining);
		if (retval != ERROR_OK) {
			if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
				/* if block write failed (no sufficient working area),
				 * we use normal (slow) single dword accesses */
				LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
			} else if (retval == ERROR_FLASH_OPERATION_FAILED) {
				LOG_ERROR("flash writing failed");
				return ERROR_FLASH_OPERATION_FAILED;
			}
		} else {
			buffer += words_remaining * 2;
			address += words_remaining * 2;
			words_remaining = 0;
		}
	}

	while (words_remaining > 0) {
		bank_adr = address & ~0x03;

		/* write data command */
		target_write_u16(target, bank_adr, 0x40);
		target_write_memory(target, address, 2, 1, buffer + bytes_written);

		/* get status command */
		target_write_u16(target, bank_adr, 0x70);

		int timeout;
		for (timeout = 0; timeout < 1000; timeout++) {
			target_read_u8(target, bank_adr, &status);
			if (status & 0x80)
				break;
			alive_sleep(1);
		}
		if (timeout == 1000) {
			LOG_ERROR("write timed out");
			return ERROR_FAIL;
		}

		/* clear status reg and read array */
		target_write_u16(target, bank_adr, 0x50);
		target_write_u16(target, bank_adr, 0xFF);

		if (status & 0x10)
			return ERROR_FLASH_OPERATION_FAILED;
		else if (status & 0x02)
			return ERROR_FLASH_OPERATION_FAILED;

		bytes_written += 2;
		words_remaining--;
		address += 2;
	}

	if (bytes_remaining) {
		uint8_t last_halfword[2] = {0xff, 0xff};

		/* copy the last remaining bytes into the write buffer */
		memcpy(last_halfword, buffer+bytes_written, bytes_remaining);

		bank_adr = address & ~0x03;

		/* write data command */
		target_write_u16(target, bank_adr, 0x40);
		target_write_memory(target, address, 2, 1, last_halfword);

		/* query status command */
		target_write_u16(target, bank_adr, 0x70);

		int timeout;
		for (timeout = 0; timeout < 1000; timeout++) {
			target_read_u8(target, bank_adr, &status);
			if (status & 0x80)
				break;
			alive_sleep(1);
		}
		if (timeout == 1000) {
			LOG_ERROR("write timed out");
			return ERROR_FAIL;
		}

		/* clear status reg and read array */
		target_write_u16(target, bank_adr, 0x50);
		target_write_u16(target, bank_adr, 0xFF);

		if (status & 0x10)
			return ERROR_FLASH_OPERATION_FAILED;
		else if (status & 0x02)
			return ERROR_FLASH_OPERATION_FAILED;
	}

	return ERROR_OK;
}
Beispiel #17
0
/** Generates a CRC32 checksum of a memory region. */
int armv7m_checksum_memory(struct target *target,
		uint32_t address, uint32_t count, uint32_t* checksum)
{
	struct working_area *crc_algorithm;
	struct armv7m_algorithm armv7m_info;
	struct reg_param reg_params[2];
	int retval;

	/* see contib/loaders/checksum/armv7m_crc.s for src */

	static const uint16_t cortex_m3_crc_code[] = {
		0x4602,					/* mov	r2, r0 */
		0xF04F, 0x30FF,			/* mov	r0, #0xffffffff */
		0x460B,					/* mov	r3, r1 */
		0xF04F, 0x0400,			/* mov	r4, #0 */
		0xE013,					/* b	ncomp */
								/* nbyte: */
		0x5D11,					/* ldrb	r1, [r2, r4] */
		0xF8DF, 0x7028,			/* ldr		r7, CRC32XOR */
		0xEA80, 0x6001,			/* eor		r0, r0, r1, asl #24 */

		0xF04F, 0x0500,			/* mov		r5, #0 */
								/* loop: */
		0x2800,					/* cmp		r0, #0 */
		0xEA4F, 0x0640,			/* mov		r6, r0, asl #1 */
		0xF105, 0x0501,			/* add		r5, r5, #1 */
		0x4630,					/* mov		r0, r6 */
		0xBFB8,					/* it		lt */
		0xEA86, 0x0007,			/* eor		r0, r6, r7 */
		0x2D08, 				/* cmp		r5, #8 */
		0xD1F4,					/* bne		loop */

		0xF104, 0x0401,			/* add	r4, r4, #1 */
								/* ncomp: */
		0x429C,					/* cmp	r4, r3 */
		0xD1E9,					/* bne	nbyte */
		0xBE00,     			/* bkpt #0 */
		0x1DB7, 0x04C1			/* CRC32XOR:	.word 0x04C11DB7 */
	};

	uint32_t i;

	retval = target_alloc_working_area(target, sizeof(cortex_m3_crc_code), &crc_algorithm);
	if (retval != ERROR_OK)
		return retval;

	/* convert flash writing code into a buffer in target endianness */
	for (i = 0; i < ARRAY_SIZE(cortex_m3_crc_code); i++) {
		retval = target_write_u16(target, crc_algorithm->address + i*sizeof(uint16_t), cortex_m3_crc_code[i]);
		if (retval != ERROR_OK)
			goto cleanup;
	}

	armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
	armv7m_info.core_mode = ARMV7M_MODE_ANY;

	init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
	init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);

	buf_set_u32(reg_params[0].value, 0, 32, address);
	buf_set_u32(reg_params[1].value, 0, 32, count);

	int timeout = 20000 * (1 + (count / (1024 * 1024)));

	retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,
	                              crc_algorithm->address + (sizeof(cortex_m3_crc_code) - 6),
	                              timeout, &armv7m_info);

	if (retval == ERROR_OK)
		*checksum = buf_get_u32(reg_params[0].value, 0, 32);
	else
		LOG_ERROR("error executing cortex_m3 crc algorithm");

	destroy_reg_param(&reg_params[0]);
	destroy_reg_param(&reg_params[1]);

cleanup:
	target_free_working_area(target, crc_algorithm);

	return retval;
}