Ejemplo n.º 1
0
static int stlink_usb_read_reg(void *handle, int num, uint32_t *val)
{
	int res;
	struct stlink_usb_handle_s *h;

	assert(handle != NULL);

	h = (struct stlink_usb_handle_s *)handle;

	stlink_usb_init_buffer(handle, STLINK_RX_EP, h->jtag_api == STLINK_JTAG_API_V1 ? 4 : 8);

	h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
	if (h->jtag_api == STLINK_JTAG_API_V1)
		h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_READREG;
	else
		h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READREG;
	h->cmdbuf[h->cmdidx++] = num;

	res = stlink_usb_xfer(handle, h->databuf, h->jtag_api == STLINK_JTAG_API_V1 ? 4 : 8);

	if (res != ERROR_OK)
		return res;

	if (h->jtag_api == STLINK_JTAG_API_V1)
		*val = le_to_h_u32(h->databuf);
	else {
		*val = le_to_h_u32(h->databuf + 4);
		return h->databuf[0] == STLINK_DEBUG_ERR_OK ? ERROR_OK : ERROR_FAIL;
	}

	return ERROR_OK;
}
Ejemplo n.º 2
0
static int stlink_usb_check_voltage(void *handle, float *target_voltage)
{
	struct stlink_usb_handle_s *h = handle;
	uint32_t adc_results[2];

	/* only supported by stlink/v2 and for firmware >= 13 */
	if (h->version.stlink == 1 || h->version.jtag < 13)
		return ERROR_COMMAND_NOTFOUND;

	stlink_usb_init_buffer(handle, h->rx_ep, 8);

	h->cmdbuf[h->cmdidx++] = STLINK_GET_TARGET_VOLTAGE;

	int result = stlink_usb_xfer(handle, h->databuf, 8);

	if (result != ERROR_OK)
		return result;

	/* convert result */
	adc_results[0] = le_to_h_u32(h->databuf);
	adc_results[1] = le_to_h_u32(h->databuf + 4);

	*target_voltage = 0;

	if (adc_results[0])
		*target_voltage = 2 * ((float)adc_results[1]) * (float)(1.2 / adc_results[0]);

	LOG_INFO("Target voltage: %f", (double)*target_voltage);

	return ERROR_OK;
}
Ejemplo n.º 3
0
static int stlink_usb_v2_read_debug_reg(void *handle, uint32_t addr, uint32_t *val)
{
	struct stlink_usb_handle_s *h;
	int res;

	assert(handle != NULL);

	h = (struct stlink_usb_handle_s *)handle;

	stlink_usb_init_buffer(handle, STLINK_RX_EP, 8);

	h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
	h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READDEBUGREG;
	h_u32_to_le(h->cmdbuf+h->cmdidx, addr);
	h->cmdidx += 4;

	res = stlink_usb_xfer(handle, h->databuf, 8);

	if (res != ERROR_OK)
		return res;

	*val = le_to_h_u32(h->databuf + 4);

	return h->databuf[0] == STLINK_DEBUG_ERR_OK ? ERROR_OK : ERROR_FAIL;
}
Ejemplo n.º 4
0
static int stlink_usb_idcode(void *handle, uint32_t *idcode)
{
	int res;
	struct stlink_usb_handle_s *h;

	assert(handle != NULL);

	h = (struct stlink_usb_handle_s *)handle;

	stlink_usb_init_buffer(handle, STLINK_RX_EP, 4);

	h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
	h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READCOREID;

	res = stlink_usb_xfer(handle, h->databuf, 4);

	if (res != ERROR_OK)
		return res;

	*idcode = le_to_h_u32(h->databuf);

	LOG_DEBUG("IDCODE: 0x%08X", *idcode);

	return ERROR_OK;
}
Ejemplo n.º 5
0
static int icdi_usb_read_reg(void *handle, int num, uint32_t *val)
{
	int result;
	struct icdi_usb_handle_s *h = handle;
	char cmd[10];

	snprintf(cmd, sizeof(cmd), "p%x", num);
	result = icdi_send_cmd(handle, cmd);
	if (result != ERROR_OK)
		return result;

	/* check result */
	result = icdi_get_cmd_result(handle);
	if (result != ERROR_OK) {
		LOG_ERROR("register read failed: 0x%x", result);
		return ERROR_FAIL;
	}

	/* convert result */
	uint8_t buf[4];
	if (unhexify(buf, h->read_buffer + 2, 4) != 4) {
		LOG_ERROR("failed to convert result");
		return ERROR_FAIL;
	}
	*val = le_to_h_u32(buf);

	return result;
}
Ejemplo n.º 6
0
int s3c2440_write_block_data(struct nand_device *nand, uint8_t *data, int data_size)
{
	struct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;
	struct target *target = nand->target;
	uint32_t nfdata = s3c24xx_info->data;
	uint32_t tmp;

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

	while (data_size >= 4) {
		tmp = le_to_h_u32(data);
		target_write_u32(target, nfdata, tmp);

		data_size -= 4;
		data += 4;
	}

	while (data_size > 0) {
		target_write_u8(target, nfdata, *data);

		data_size -= 1;
		data += 1;
	}

	return ERROR_OK;
}
Ejemplo n.º 7
0
static enum target_state icdi_usb_state(void *handle)
{
	int result;
	struct icdi_usb_handle_s *h = handle;
	uint32_t dhcsr;
	uint8_t buf[4];

	result = icdi_usb_read_mem(h, DCB_DHCSR, 4, 1, buf);
	if (result != ERROR_OK)
		return TARGET_UNKNOWN;

	/* REVISIT: There's no target pointer here so there's no way to use target_buffer_get_u32().
	 * I guess all supported chips are little-endian anyway. */
	dhcsr = le_to_h_u32(buf);
	if (dhcsr & S_HALT)
		return TARGET_HALTED;

	return TARGET_RUNNING;
}
Ejemplo n.º 8
0
/* The Cortex M3 will indicate that an alignment adjustment
 * has been done on the stack by setting bit 9 of the stacked xPSR
 * register.  In this case, we can just add an extra 4 bytes to get
 * to the program stack.  Note that some places in the ARM documentation
 * make this a little unclear but the padding takes place before the
 * normal exception stacking - so xPSR is always available at a fixed
 * location.
 *
 * Relevant documentation:
 *    Cortex-M series processors -> Cortex-M3 -> Revision: xxx ->
 *        Cortex-M3 Devices Generic User Guide -> The Cortex-M3 Processor ->
 *        Exception Model -> Exception entry and return -> Exception entry
 *    Cortex-M series processors -> Cortex-M3 -> Revision: xxx ->
 *        Cortex-M3 Devices Generic User Guide -> Cortex-M3 Peripherals ->
 *        System control block -> Configuration and Control Register (STKALIGN)
 *
 * This is just a helper function for use in the calculate_process_stack
 * function for a given architecture/rtos.
 */
int64_t rtos_Cortex_M_stack_align(struct target *target,
	const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
	int64_t stack_ptr, size_t xpsr_offset)
{
	const uint32_t ALIGN_NEEDED = (1 << 9);
	uint32_t xpsr;
	int64_t new_stack_ptr;

	new_stack_ptr = stack_ptr - stacking->stack_growth_direction *
		stacking->stack_registers_size;
	xpsr = (target->endianness == TARGET_LITTLE_ENDIAN) ?
			le_to_h_u32(&stack_data[xpsr_offset]) :
			be_to_h_u32(&stack_data[xpsr_offset]);
	if ((xpsr & ALIGN_NEEDED) != 0) {
		LOG_DEBUG("XPSR(0x%08" PRIx32 ") indicated stack alignment was necessary\r\n",
			xpsr);
		new_stack_ptr -= (stacking->stack_growth_direction * 4);
	}
	return new_stack_ptr;
}
Ejemplo n.º 9
0
/**
 * Runs ARM code in the target to check whether a memory block holds
 * all ones.  NOR flash which has been erased, and thus may be written,
 * holds all ones.
 *
 */
int arm_blank_check_memory(struct target *target,
	uint32_t address, uint32_t count, uint32_t *blank)
{
	struct working_area *check_algorithm;
	struct reg_param reg_params[3];
	struct arm_algorithm arm_algo;
	struct arm *arm = target_to_arm(target);
	int retval;
	uint32_t i;
	uint32_t exit_var = 0;

	static const uint8_t check_code_le[] = {
#include "../../contrib/loaders/erase_check/armv4_5_erase_check.inc"
	};

	assert(sizeof(check_code_le) % 4 == 0);

	/* make sure we have a working area */
	retval = target_alloc_working_area(target,
			sizeof(check_code_le), &check_algorithm);
	if (retval != ERROR_OK)
		return retval;

	/* convert code into a buffer in target endianness */
	for (i = 0; i < ARRAY_SIZE(check_code_le) / 4; i++) {
		retval = target_write_u32(target,
				check_algorithm->address
				+ i * sizeof(uint32_t),
				le_to_h_u32(&check_code_le[i * 4]));
		if (retval != ERROR_OK)
			goto cleanup;
	}

	arm_algo.common_magic = ARM_COMMON_MAGIC;
	arm_algo.core_mode = ARM_MODE_SVC;
	arm_algo.core_state = ARM_STATE_ARM;

	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);

	/* armv4 must exit using a hardware breakpoint */
	if (arm->is_armv4)
		exit_var = check_algorithm->address + sizeof(check_code_le) - 4;

	retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
			check_algorithm->address,
			exit_var,
			10000, &arm_algo);

	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]);

cleanup:
	target_free_working_area(target, check_algorithm);

	return retval;
}
Ejemplo n.º 10
0
/* read JTAG buffer into little-endian u16, flipping bit-order */
int arm_jtag_buf_to_le16_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
    h_u16_to_le(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32) & 0xffff);
    return ERROR_OK;
}
Ejemplo n.º 11
0
static int stlink_usb_open(struct hl_interface_param_s *param, void **fd)
{
	int err, retry_count = 1;
	struct stlink_usb_handle_s *h;
	enum stlink_jtag_api_version api;

	LOG_DEBUG("stlink_usb_open");

	h = calloc(1, sizeof(struct stlink_usb_handle_s));

	if (h == 0) {
		LOG_DEBUG("malloc failed");
		return ERROR_FAIL;
	}

	h->transport = param->transport;

	const uint16_t vids[] = { param->vid, 0 };
	const uint16_t pids[] = { param->pid, 0 };

	LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param->transport,
		param->vid, param->pid);

	/*
	  On certain host USB configurations(e.g. MacBook Air)
	  STLINKv2 dongle seems to have its FW in a funky state if,
	  after plugging it in, you try to use openocd with it more
	  then once (by launching and closing openocd). In cases like
	  that initial attempt to read the FW info via
	  stlink_usb_version will fail and the device has to be reset
	  in order to become operational.
	 */
	do {
		if (jtag_libusb_open(vids, pids, &h->fd) != ERROR_OK) {
			LOG_ERROR("open failed");
			goto error_open;
		}

		jtag_libusb_set_configuration(h->fd, 0);

		if (jtag_libusb_claim_interface(h->fd, 0) != ERROR_OK) {
			LOG_DEBUG("claim interface failed");
			goto error_open;
		}

		/* RX EP is common for all versions */
		h->rx_ep = STLINK_RX_EP;

		/* wrap version for first read */
		switch (param->pid) {
			case STLINK_V1_PID:
				h->version.stlink = 1;
				h->tx_ep = STLINK_TX_EP;
				h->trace_ep = STLINK_TRACE_EP;
				break;
			case STLINK_V2_1_PID:
				h->version.stlink = 2;
				h->tx_ep = STLINK_V2_1_TX_EP;
				h->trace_ep = STLINK_V2_1_TRACE_EP;
				break;
			default:
			/* fall through - we assume V2 to be the default version*/
			case STLINK_V2_PID:
				h->version.stlink = 2;
				h->tx_ep = STLINK_TX_EP;
				h->trace_ep = STLINK_TRACE_EP;
				break;
		}

		/* get the device version */
		err = stlink_usb_version(h);

		if (err == ERROR_OK) {
			break;
		} else if (h->version.stlink == 1 ||
			   retry_count == 0) {
			LOG_ERROR("read version failed");
			goto error_open;
		} else {
			err = jtag_libusb_release_interface(h->fd, 0);
			if (err != ERROR_OK) {
				LOG_ERROR("release interface failed");
				goto error_open;
			}

			err = jtag_libusb_reset_device(h->fd);
			if (err != ERROR_OK) {
				LOG_ERROR("reset device failed");
				goto error_open;
			}

			jtag_libusb_close(h->fd);
			/*
			  Give the device one second to settle down and
			  reenumerate.
			 */
			usleep(1 * 1000 * 1000);
			retry_count--;
		}
	} while (1);

	/* compare usb vid/pid */
	if ((param->vid != h->vid) || (param->pid != h->pid))
		LOG_INFO("vid/pid are not identical: 0x%04X/0x%04X 0x%04X/0x%04X",
			param->vid, param->pid,
			h->vid, h->pid);

	/* check if mode is supported */
	err = ERROR_OK;

	switch (h->transport) {
		case HL_TRANSPORT_SWD:
		case HL_TRANSPORT_JTAG:
			if (h->version.jtag == 0)
				err = ERROR_FAIL;
			break;
		case HL_TRANSPORT_SWIM:
			if (h->version.swim == 0)
				err = ERROR_FAIL;
			break;
		default:
			err = ERROR_FAIL;
			break;
	}

	if (err != ERROR_OK) {
		LOG_ERROR("mode (transport) not supported by device");
		goto error_open;
	}

	api = h->version.jtag_api_max;

	LOG_INFO("using stlink api v%d", api);

	/* set the used jtag api, this will default to the newest supported version */
	h->jtag_api = api;

	if (h->jtag_api >= 2 && param->trace_source_hz > 0) {
		uint32_t prescale;

		prescale = param->trace_source_hz > STLINK_TRACE_MAX_HZ ?
			(param->trace_source_hz / STLINK_TRACE_MAX_HZ) - 1 : 0;

		h->trace.output_f = param->trace_f;
		h->trace.source_hz = param->trace_source_hz;
		h->trace.prescale = prescale;
	}

	/* initialize the debug hardware */
	err = stlink_usb_init_mode(h, param->connect_under_reset);

	if (err != ERROR_OK) {
		LOG_ERROR("init mode failed");
		goto error_open;
	}

	/* get cpuid, so we can determine the max page size
	 * start with a safe default */
	h->max_mem_packet = (1 << 10);

	uint8_t buffer[4];
	err = stlink_usb_read_mem32(h, CPUID, 4, buffer);
	if (err == ERROR_OK) {
		uint32_t cpuid = le_to_h_u32(buffer);
		int i = (cpuid >> 4) & 0xf;
		if (i == 4 || i == 3) {
			/* Cortex-M3/M4 has 4096 bytes autoincrement range */
			h->max_mem_packet = (1 << 12);
		}
	}
Ejemplo n.º 12
0
/* read JTAG buffer into u8 */
int arm_jtag_buf_to_8(u8 *in_buf, void *priv, struct scan_field_s *field)
{
    u8 *dest = priv;
    *dest = le_to_h_u32(in_buf) & 0xff;
    return ERROR_OK;
}
Ejemplo n.º 13
0
/* read JTAG buffer into big-endian u16 */
int arm_jtag_buf_to_be16(u8 *in_buf, void *priv, struct scan_field_s *field)
{
    h_u16_to_be(((u8*)priv), le_to_h_u32(in_buf) & 0xffff);
    return ERROR_OK;
}
Ejemplo n.º 14
0
/* read JTAG buffer into little-endian u32 */
int arm_jtag_buf_to_le32(u8 *in_buf, void *priv, struct scan_field_s *field)
{
    h_u32_to_le(((u8*)priv), le_to_h_u32(in_buf));
    return ERROR_OK;
}
Ejemplo n.º 15
0
/* read JTAG buffer into big-endian u32, flipping bit-order */
int arm_jtag_buf_to_be32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
    h_u32_to_be(((u8*)priv), flip_u32(le_to_h_u32(in_buf), 32));
    return ERROR_OK;
}
Ejemplo n.º 16
0
/**
 * Runs ARM code in the target to calculate a CRC32 checksum.
 *
 */
int arm_checksum_memory(struct target *target,
	uint32_t address, uint32_t count, uint32_t *checksum)
{
	struct working_area *crc_algorithm;
	struct arm_algorithm arm_algo;
	struct arm *arm = target_to_arm(target);
	struct reg_param reg_params[2];
	int retval;
	uint32_t i;
	uint32_t exit_var = 0;

	static const uint8_t arm_crc_code_le[] = {
#include "../../contrib/loaders/checksum/armv4_5_crc.inc"
	};

	assert(sizeof(arm_crc_code_le) % 4 == 0);

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

	/* convert code into a buffer in target endianness */
	for (i = 0; i < ARRAY_SIZE(arm_crc_code_le) / 4; i++) {
		retval = target_write_u32(target,
				crc_algorithm->address + i * sizeof(uint32_t),
				le_to_h_u32(&arm_crc_code_le[i * 4]));
		if (retval != ERROR_OK)
			goto cleanup;
	}

	arm_algo.common_magic = ARM_COMMON_MAGIC;
	arm_algo.core_mode = ARM_MODE_SVC;
	arm_algo.core_state = ARM_STATE_ARM;

	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);

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

	/* armv4 must exit using a hardware breakpoint */
	if (arm->is_armv4)
		exit_var = crc_algorithm->address + sizeof(arm_crc_code_le) - 8;

	retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
			crc_algorithm->address,
			exit_var,
			timeout, &arm_algo);

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

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

cleanup:
	target_free_working_area(target, crc_algorithm);

	return retval;
}
Ejemplo n.º 17
0
static __inline__ void virtexflip32(jtag_callback_data_t arg)
{
  uint8_t *in = (uint8_t *)arg;
	*((uint32_t *)in) = flip_u32(le_to_h_u32(in), 32);
}
Ejemplo n.º 18
0
/* read JTAG buffer into host-endian u32, flipping bit-order */
int arm_jtag_buf_to_u32_flip(u8 *in_buf, void *priv, struct scan_field_s *field)
{
    u32 *dest = priv;
    *dest = flip_u32(le_to_h_u32(in_buf), 32);
    return ERROR_OK;
}