コード例 #1
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static int str9xpec_write_options(struct flash_bank *bank)
{
	struct scan_field field;
	uint8_t status;
	struct jtag_tap *tap;
	struct str9xpec_flash_controller *str9xpec_info = NULL;

	str9xpec_info = bank->driver_priv;
	tap = str9xpec_info->tap;

	/* erase config options first */
	status = str9xpec_erase_area(bank, 0xFE, 0xFE);

	if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
		return status;

	if (!str9xpec_info->isc_enable)
		str9xpec_isc_enable(bank);

	if (!str9xpec_info->isc_enable)
		return ISC_STATUS_ERROR;

	/* according to data 64th bit has to be set */
	buf_set_u32(str9xpec_info->options, 63, 1, 1);

	/* set option byte address */
	str9xpec_set_address(bank, 0x50);

	/* execute ISC_PROGRAM command */
	str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);

	field.num_bits = 64;
	field.out_value = str9xpec_info->options;
	field.in_value = NULL;

	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);

	/* small delay before polling */
	jtag_add_sleep(50);

	str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);

	do {
		field.num_bits = 8;
		field.out_value = NULL;
		field.in_value = &status;

		jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
		jtag_execute_queue();

	} while (!(status & ISC_STATUS_BUSY));

	str9xpec_isc_disable(bank);

	return status;
}
コード例 #2
0
ファイル: str9xpec.c プロジェクト: unnamet/estick-jtag
u8 str9xpec_isc_status(jtag_tap_t *tap)
{
	scan_field_t field;
	u8 status;

	if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
		return ISC_STATUS_ERROR;

	field.tap = tap;
	field.num_bits = 8;
	field.out_value = NULL;
	field.out_mask = NULL;
	field.in_value = &status;
	field.in_check_value = NULL;
	field.in_check_mask = NULL;
	field.in_handler = NULL;
	field.in_handler_priv = NULL;

	jtag_add_dr_scan(1, &field, TAP_IDLE);
	jtag_execute_queue();

	LOG_DEBUG("status: 0x%2.2x", status);

	if (status & ISC_STATUS_SECURITY)
		LOG_INFO("Device Security Bit Set");

	return status;
}
コード例 #3
0
ファイル: str9xpec.c プロジェクト: unnamet/estick-jtag
int str9xpec_read_config(struct flash_bank_s *bank)
{
	scan_field_t field;
	u8 status;
	jtag_tap_t *tap;

	str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;

	tap = str9xpec_info->tap;

	LOG_DEBUG("ISC_CONFIGURATION");

	/* execute ISC_CONFIGURATION command */
	str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);

	field.tap = tap;
	field.num_bits = 64;
	field.out_value = NULL;
	field.out_mask = NULL;
	field.in_value = str9xpec_info->options;
	field.in_check_value = NULL;
	field.in_check_mask = NULL;
	field.in_handler = NULL;
	field.in_handler_priv = NULL;

	jtag_add_dr_scan(1, &field, TAP_IDLE);
	jtag_execute_queue();

	status = str9xpec_isc_status(tap);

	return status;
}
コード例 #4
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static int str9xpec_isc_enable(struct flash_bank *bank)
{
	uint8_t status;
	struct jtag_tap *tap;
	struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;

	tap = str9xpec_info->tap;

	if (str9xpec_info->isc_enable)
		return ERROR_OK;

	/* enter isc mode */
	if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
		return ERROR_TARGET_INVALID;

	/* check ISC status */
	status = str9xpec_isc_status(tap);
	if (status & ISC_STATUS_MODE) {
		/* we have entered isc mode */
		str9xpec_info->isc_enable = 1;
		LOG_DEBUG("ISC_MODE Enabled");
	}

	return ERROR_OK;
}
コード例 #5
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
{
	struct scan_field field;
	uint8_t status;
	struct jtag_tap *tap;
	int i;
	uint8_t *buffer = NULL;

	struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;

	tap = str9xpec_info->tap;

	if (!str9xpec_info->isc_enable)
		str9xpec_isc_enable(bank);

	if (!str9xpec_info->isc_enable)
		return ERROR_FLASH_OPERATION_FAILED;

	buffer = calloc(DIV_ROUND_UP(64, 8), 1);

	LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);

	for (i = first; i <= last; i++)
		buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);

	/* execute ISC_BLANK_CHECK command */
	str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);

	field.num_bits = 64;
	field.out_value = buffer;
	field.in_value = NULL;

	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
	jtag_add_sleep(40000);

	/* read blank check result */
	field.num_bits = 64;
	field.out_value = NULL;
	field.in_value = buffer;

	jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
	jtag_execute_queue();

	status = str9xpec_isc_status(tap);

	for (i = first; i <= last; i++) {
		if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
			bank->sectors[i].is_erased = 0;
		else
			bank->sectors[i].is_erased = 1;
	}

	free(buffer);

	str9xpec_isc_disable(bank);

	if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
		return ERROR_FLASH_OPERATION_FAILED;
	return ERROR_OK;
}
コード例 #6
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static int str9xpec_isc_disable(struct flash_bank *bank)
{
	uint8_t status;
	struct jtag_tap *tap;
	struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;

	tap = str9xpec_info->tap;

	if (!str9xpec_info->isc_enable)
		return ERROR_OK;

	if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
		return ERROR_TARGET_INVALID;

	/* delay to handle aborts */
	jtag_add_sleep(50);

	/* check ISC status */
	status = str9xpec_isc_status(tap);
	if (!(status & ISC_STATUS_MODE)) {
		/* we have left isc mode */
		str9xpec_info->isc_enable = 0;
		LOG_DEBUG("ISC_MODE Disabled");
	}

	return ERROR_OK;
}
コード例 #7
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static int str9xpec_read_config(struct flash_bank *bank)
{
	struct scan_field field;
	uint8_t status;
	struct jtag_tap *tap;

	struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;

	tap = str9xpec_info->tap;

	LOG_DEBUG("ISC_CONFIGURATION");

	/* execute ISC_CONFIGURATION command */
	str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);

	field.num_bits = 64;
	field.out_value = NULL;
	field.in_value = str9xpec_info->options;

	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
	jtag_execute_queue();

	status = str9xpec_isc_status(tap);

	return status;
}
コード例 #8
0
ファイル: str9xpec.c プロジェクト: unnamet/estick-jtag
int str9xpec_set_address(struct flash_bank_s *bank, u8 sector)
{
	jtag_tap_t *tap;
	scan_field_t field;
	str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;

	tap = str9xpec_info->tap;

	/* set flash controller address */
	str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);

	field.tap = tap;
	field.num_bits = 8;
	field.out_value = &sector;
	field.out_mask = NULL;
	field.in_value = NULL;
	field.in_check_value = NULL;
	field.in_check_mask = NULL;
	field.in_handler = NULL;
	field.in_handler_priv = NULL;

	jtag_add_dr_scan(1, &field, -1);

	return ERROR_OK;
}
コード例 #9
0
ファイル: str9xpec.c プロジェクト: unnamet/estick-jtag
int str9xpec_lock_device(struct flash_bank_s *bank)
{
	scan_field_t field;
	u8 status;
	jtag_tap_t *tap;
	str9xpec_flash_controller_t *str9xpec_info = NULL;

	str9xpec_info = bank->driver_priv;
	tap = str9xpec_info->tap;

	if (!str9xpec_info->isc_enable) {
		str9xpec_isc_enable( bank );
	}

	if (!str9xpec_info->isc_enable) {
		return ISC_STATUS_ERROR;
	}

	/* set security address */
	str9xpec_set_address(bank, 0x80);

	/* execute ISC_PROGRAM command */
	str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);

	str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);

	do {
		field.tap = tap;
		field.num_bits = 8;
		field.out_value = NULL;
		field.out_mask = NULL;
		field.in_value = &status;
		field.in_check_value = NULL;
		field.in_check_mask = NULL;
		field.in_handler = NULL;
		field.in_handler_priv = NULL;

		jtag_add_dr_scan(1, &field, -1);
		jtag_execute_queue();

	} while(!(status & ISC_STATUS_BUSY));

	str9xpec_isc_disable(bank);

	return status;
}
コード例 #10
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
{
	struct scan_field field;
	uint8_t status;
	struct jtag_tap *tap;
	int i;
	uint8_t *buffer = NULL;

	struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;

	tap = str9xpec_info->tap;

	if (!str9xpec_info->isc_enable)
		str9xpec_isc_enable(bank);

	if (!str9xpec_info->isc_enable)
		return ISC_STATUS_ERROR;

	buffer = calloc(DIV_ROUND_UP(64, 8), 1);

	LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);

	/* last bank: 0xFF signals a full erase (unlock complete device) */
	/* last bank: 0xFE signals a option byte erase */
	if (last == 0xFF) {
		for (i = 0; i < 64; i++)
			buf_set_u32(buffer, i, 1, 1);
	} else if (last == 0xFE)
		buf_set_u32(buffer, 49, 1, 1);
	else {
		for (i = first; i <= last; i++)
			buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
	}

	LOG_DEBUG("ISC_ERASE");

	/* execute ISC_ERASE command */
	str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);

	field.num_bits = 64;
	field.out_value = buffer;
	field.in_value = NULL;

	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
	jtag_execute_queue();

	jtag_add_sleep(10);

	/* wait for erase completion */
	while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY))
		alive_sleep(1);

	free(buffer);

	str9xpec_isc_disable(bank);

	return status;
}
コード例 #11
0
ファイル: str9xpec.c プロジェクト: unnamet/estick-jtag
int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	int retval;
	flash_bank_t *bank;
	jtag_tap_t *tap0;
	jtag_tap_t *tap1;
	jtag_tap_t *tap2;
	str9xpec_flash_controller_t *str9xpec_info = NULL;

	if (argc < 1)
	{
		command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
		return ERROR_OK;
	}

	bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
	if (!bank)
	{
		command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
		return ERROR_OK;
	}

	str9xpec_info = bank->driver_priv;

	tap0 = str9xpec_info->tap;

	/* remove arm core from chain - enter turbo mode */
	tap1 = tap0->next_tap;
	if (tap1 == NULL)
	{
		/* things are *WRONG* */
		command_print(cmd_ctx,"**STR9FLASH** (tap1) invalid chain?");
		return ERROR_OK;
	}
	tap2 = tap1->next_tap;
	if (tap2 == NULL)
	{
		/* things are *WRONG* */
		command_print(cmd_ctx,"**STR9FLASH** (tap2) invalid chain?");
		return ERROR_OK;
	}

	/* enable turbo mode - TURBO-PROG-ENABLE */
	str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
	if ((retval = jtag_execute_queue()) != ERROR_OK)
		return retval;

	/* modify scan chain - str9 core has been removed */
	tap1->enabled = 0;

	return ERROR_OK;
}
コード例 #12
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static int str9xpec_lock_device(struct flash_bank *bank)
{
	struct scan_field field;
	uint8_t status;
	struct jtag_tap *tap;
	struct str9xpec_flash_controller *str9xpec_info = NULL;

	str9xpec_info = bank->driver_priv;
	tap = str9xpec_info->tap;

	if (!str9xpec_info->isc_enable)
		str9xpec_isc_enable(bank);

	if (!str9xpec_info->isc_enable)
		return ISC_STATUS_ERROR;

	/* set security address */
	str9xpec_set_address(bank, 0x80);

	/* execute ISC_PROGRAM command */
	str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);

	str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);

	do {
		field.num_bits = 8;
		field.out_value = NULL;
		field.in_value = &status;

		jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
		jtag_execute_queue();

	} while (!(status & ISC_STATUS_BUSY));

	str9xpec_isc_disable(bank);

	return status;
}
コード例 #13
0
ファイル: str9xpec.c プロジェクト: unnamet/estick-jtag
int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	flash_bank_t *bank;
	scan_field_t field;
	u8 *buffer = NULL;
	jtag_tap_t *tap;
	u32 idcode;
	str9xpec_flash_controller_t *str9xpec_info = NULL;

	if (argc < 1)
	{
		return ERROR_COMMAND_SYNTAX_ERROR;
	}

	bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
	if (!bank)
	{
		command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
		return ERROR_OK;
	}

	str9xpec_info = bank->driver_priv;
	tap = str9xpec_info->tap;

	buffer = calloc(CEIL(32, 8), 1);

	str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);

	field.tap = tap;
	field.num_bits = 32;
	field.out_value = NULL;
	field.out_mask = NULL;
	field.in_value = buffer;
	field.in_check_value = NULL;
	field.in_check_mask = NULL;
	field.in_handler = NULL;
	field.in_handler_priv = NULL;

	jtag_add_dr_scan(1, &field, TAP_IDLE);
	jtag_execute_queue();

	idcode = buf_get_u32(buffer, 0, 32);

	command_print(cmd_ctx, "str9xpec part id: 0x%8.8x", idcode);

	free(buffer);

	return ERROR_OK;
}
コード例 #14
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
{
	struct jtag_tap *tap;
	struct scan_field field;
	struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;

	tap = str9xpec_info->tap;

	/* set flash controller address */
	str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);

	field.num_bits = 8;
	field.out_value = &sector;
	field.in_value = NULL;

	jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);

	return ERROR_OK;
}
コード例 #15
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
{
	struct scan_field field;
	uint8_t status;

	if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
		return ISC_STATUS_ERROR;

	field.num_bits = 8;
	field.out_value = NULL;
	field.in_value = &status;


	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
	jtag_execute_queue();

	LOG_DEBUG("status: 0x%2.2x", status);

	if (status & ISC_STATUS_SECURITY)
		LOG_INFO("Device Security Bit Set");

	return status;
}
コード例 #16
0
ファイル: str9xpec.c プロジェクト: unnamet/estick-jtag
int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	flash_bank_t *bank;
	jtag_tap_t *tap;
	str9xpec_flash_controller_t *str9xpec_info = NULL;

	if (argc < 1)
	{
		command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
		return ERROR_OK;
	}

	bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
	if (!bank)
	{
		command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
		return ERROR_OK;
	}

	str9xpec_info = bank->driver_priv;
	tap = str9xpec_info->tap;

	if (tap == NULL)
		return ERROR_FAIL;

	/* exit turbo mode via RESET */
	str9xpec_set_instr(tap, ISC_NOOP, TAP_RESET);
	jtag_execute_queue();

	/* restore previous scan chain */
	if (tap->next_tap) {
		tap->next_tap->enabled = 1;
	}

	return ERROR_OK;
}
コード例 #17
0
ファイル: str9xpec.c プロジェクト: 01org/CODK-A-Flashpack
static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
		uint32_t offset, uint32_t count)
{
	struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
	uint32_t dwords_remaining = (count / 8);
	uint32_t bytes_remaining = (count & 0x00000007);
	uint32_t bytes_written = 0;
	uint8_t status;
	uint32_t check_address = offset;
	struct jtag_tap *tap;
	struct scan_field field;
	uint8_t *scanbuf;
	int i;
	int first_sector = 0;
	int last_sector = 0;

	tap = str9xpec_info->tap;

	if (!str9xpec_info->isc_enable)
		str9xpec_isc_enable(bank);

	if (!str9xpec_info->isc_enable)
		return ERROR_FLASH_OPERATION_FAILED;

	if (offset & 0x7) {
		LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-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 ((offset >= sec_start) && (offset < sec_end))
			first_sector = i;

		if ((offset + count >= sec_start) && (offset + count < sec_end))
			last_sector = i;
	}

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

	LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);

	scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);

	LOG_DEBUG("ISC_PROGRAM");

	for (i = first_sector; i <= last_sector; i++) {
		str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);

		dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
				? dwords_remaining : (bank->sectors[i].size/8);

		while (dwords_remaining > 0) {
			str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);

			field.num_bits = 64;
			field.out_value = (buffer + bytes_written);
			field.in_value = NULL;

			jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);

			/* small delay before polling */
			jtag_add_sleep(50);

			str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);

			do {
				field.num_bits = 8;
				field.out_value = NULL;
				field.in_value = scanbuf;

				jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
				jtag_execute_queue();

				status = buf_get_u32(scanbuf, 0, 8);

			} while (!(status & ISC_STATUS_BUSY));

			if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
				return ERROR_FLASH_OPERATION_FAILED;

			/* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
				return ERROR_FLASH_OPERATION_FAILED; */

			dwords_remaining--;
			bytes_written += 8;
		}
	}

	if (bytes_remaining) {
		uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

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

		str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);

		field.num_bits = 64;
		field.out_value = last_dword;
		field.in_value = NULL;

		jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);

		/* small delay before polling */
		jtag_add_sleep(50);

		str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);

		do {
			field.num_bits = 8;
			field.out_value = NULL;
			field.in_value = scanbuf;

			jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
			jtag_execute_queue();

			status = buf_get_u32(scanbuf, 0, 8);

		} while (!(status & ISC_STATUS_BUSY));

		if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
			return ERROR_FLASH_OPERATION_FAILED;

		/* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
			return ERROR_FLASH_OPERATION_FAILED; */
	}

	free(scanbuf);

	str9xpec_isc_disable(bank);

	return ERROR_OK;
}