示例#1
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_set_core_reg(struct reg *reg, uint8_t *buf)
{
	struct or1k_core_reg *or1k_reg = reg->arch_info;
	struct target *target = or1k_reg->target;
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	uint32_t value = buf_get_u32(buf, 0, 32);

	LOG_DEBUG("-");

	if (target->state != TARGET_HALTED)
		return ERROR_TARGET_NOT_HALTED;

	if (or1k_reg->list_num < OR1KNUMCOREREGS) {
		buf_set_u32(reg->value, 0, 32, value);
		reg->dirty = 1;
		reg->valid = 1;
	} else {
		/* This is an spr, write it to the HW */
		int retval = du_core->or1k_jtag_write_cpu(&or1k->jtag,
							  or1k_reg->spr_num, 1, &value);
		if (retval != ERROR_OK) {
			LOG_ERROR("Error while writing spr 0x%08" PRIx32, or1k_reg->spr_num);
			return retval;
		}
	}

	return ERROR_OK;
}
示例#2
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_examine(struct target *target)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);

	if (!target_was_examined(target)) {

		target_set_examined(target);

		int running;

		int retval = du_core->or1k_is_cpu_running(&or1k->jtag, &running);
		if (retval != ERROR_OK) {
			LOG_ERROR("Couldn't read the CPU state");
			return retval;
		} else {
			if (running)
				target->state = TARGET_RUNNING;
			else {
				LOG_DEBUG("Target is halted");

				/* This is the first time we examine the target,
				 * it is stalled and we don't know why. Let's
				 * assume this is because of a debug reason.
				 */
				if (target->state == TARGET_UNKNOWN)
					target->debug_reason = DBG_REASON_DBGRQ;

				target->state = TARGET_HALTED;
			}
		}
	}

	return ERROR_OK;
}
示例#3
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_read_core_reg(struct target *target, int num)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	uint32_t reg_value;

	LOG_DEBUG("-");

	if ((num < 0) || (num >= or1k->nb_regs))
		return ERROR_COMMAND_SYNTAX_ERROR;

	if ((num >= 0) && (num < OR1KNUMCOREREGS)) {
		reg_value = or1k->core_regs[num];
		buf_set_u32(or1k->core_cache->reg_list[num].value, 0, 32, reg_value);
		LOG_DEBUG("Read core reg %i value 0x%08" PRIx32, num , reg_value);
		or1k->core_cache->reg_list[num].valid = 1;
		or1k->core_cache->reg_list[num].dirty = 0;
	} else {
		/* This is an spr, always read value from HW */
		int retval = du_core->or1k_jtag_read_cpu(&or1k->jtag,
							 or1k->arch_info[num].spr_num, 1, &reg_value);
		if (retval != ERROR_OK) {
			LOG_ERROR("Error while reading spr 0x%08" PRIx32, or1k->arch_info[num].spr_num);
			return retval;
		}
		buf_set_u32(or1k->core_cache->reg_list[num].value, 0, 32, reg_value);
		LOG_DEBUG("Read spr reg %i value 0x%08" PRIx32, num , reg_value);
	}

	return ERROR_OK;
}
示例#4
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_save_context(struct target *target)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	int regs_read = 0;
	int retval;

	LOG_DEBUG("-");

	for (int i = 0; i < OR1KNUMCOREREGS; i++) {
		if (!or1k->core_cache->reg_list[i].valid) {
			if (i == OR1K_REG_PPC || i == OR1K_REG_NPC || i == OR1K_REG_SR) {
				retval = du_core->or1k_jtag_read_cpu(&or1k->jtag,
						or1k->arch_info[i].spr_num, 1,
						&or1k->core_regs[i]);
				if (retval != ERROR_OK)
					return retval;
			} else if (!regs_read) {
				/* read gpr registers at once (but only one time in this loop) */
				retval = or1k_jtag_read_regs(or1k, or1k->core_regs);
				if (retval != ERROR_OK)
					return retval;
				/* prevent next reads in this loop */
				regs_read = 1;
			}
			/* We've just updated the core_reg[i], now update
			   the core cache */
			or1k_read_core_reg(target, i);
		}
	}

	return ERROR_OK;
}
示例#5
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_init_target(struct command_context *cmd_ctx,
		struct target *target)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	struct or1k_jtag *jtag = &or1k->jtag;

	if (du_core == NULL) {
		LOG_ERROR("No debug unit selected");
		return ERROR_FAIL;
	}

	if (jtag->tap_ip == NULL) {
		LOG_ERROR("No tap selected");
		return ERROR_FAIL;
	}

	or1k->jtag.tap = target->tap;
	or1k->jtag.or1k_jtag_inited = 0;
	or1k->jtag.or1k_jtag_module_selected = -1;
	or1k->jtag.target = target;

	or1k_build_reg_cache(target);

	return ERROR_OK;
}
示例#6
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_write_memory(struct target *target, uint32_t address,
		uint32_t size, uint32_t count, const uint8_t *buffer)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);

	LOG_DEBUG("Write memory at 0x%08" PRIx32 ", size: %" PRIu32 ", count: 0x%08" PRIx32, address, size, count);

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

	/* Sanitize arguments */
	if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !buffer) {
		LOG_ERROR("Bad arguments");
		return ERROR_COMMAND_SYNTAX_ERROR;
	}

	if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) {
		LOG_ERROR("Can't handle unaligned memory access");
		return ERROR_TARGET_UNALIGNED_ACCESS;
	}

	return du_core->or1k_jtag_write_memory(&or1k->jtag, address, size, count, buffer);
}
示例#7
0
static int or1k_add_breakpoint(struct target *target,
			       struct breakpoint *breakpoint)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	uint8_t data;

	LOG_DEBUG("Adding breakpoint: addr 0x%08" TARGET_PRIxADDR ", len %d, type %d, set: %d, id: %" PRId32,
		  breakpoint->address, breakpoint->length, breakpoint->type,
		  breakpoint->set, breakpoint->unique_id);

	/* Only support SW breakpoints for now. */
	if (breakpoint->type == BKPT_HARD)
		LOG_ERROR("HW breakpoints not supported for now. Doing SW breakpoint.");

	/* Read and save the instruction */
	int retval = du_core->or1k_jtag_read_memory(&or1k->jtag,
					 breakpoint->address,
					 4,
					 1,
					 &data);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while reading the instruction at 0x%08" TARGET_PRIxADDR,
			   breakpoint->address);
		return retval;
	}

	if (breakpoint->orig_instr != NULL)
		free(breakpoint->orig_instr);

	breakpoint->orig_instr = malloc(breakpoint->length);
	memcpy(breakpoint->orig_instr, &data, breakpoint->length);

	/* Sub in the OR1K trap instruction */
	uint8_t or1k_trap_insn[4];
	target_buffer_set_u32(target, or1k_trap_insn, OR1K_TRAP_INSTR);
	retval = du_core->or1k_jtag_write_memory(&or1k->jtag,
					  breakpoint->address,
					  4,
					  1,
					  or1k_trap_insn);

	if (retval != ERROR_OK) {
		LOG_ERROR("Error while writing OR1K_TRAP_INSTR at 0x%08" TARGET_PRIxADDR,
			   breakpoint->address);
		return retval;
	}

	/* invalidate instruction cache */
	uint32_t addr = breakpoint->address;
	retval = du_core->or1k_jtag_write_cpu(&or1k->jtag,
			OR1K_ICBIR_CPU_REG_ADD, 1, &addr);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while invalidating the ICACHE");
		return retval;
	}

	return ERROR_OK;
}
示例#8
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_deassert_reset(struct target *target)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);

	LOG_DEBUG("-");

	int retval = du_core->or1k_cpu_reset(&or1k->jtag, CPU_NOT_RESET);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while desasserting RESET");
		return retval;
	}

	return ERROR_OK;
}
示例#9
0
文件: or1k.c 项目: FelixVi/openocd
static int or1k_profiling(struct target *target, uint32_t *samples,
		uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
{
	struct timeval timeout, now;
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	int retval = ERROR_OK;

	gettimeofday(&timeout, NULL);
	timeval_add_time(&timeout, seconds, 0);

	LOG_INFO("Starting or1k profiling. Sampling npc as fast as we can...");

	/* Make sure the target is running */
	target_poll(target);
	if (target->state == TARGET_HALTED)
		retval = target_resume(target, 1, 0, 0, 0);

	if (retval != ERROR_OK) {
		LOG_ERROR("Error while resuming target");
		return retval;
	}

	uint32_t sample_count = 0;

	for (;;) {
		uint32_t reg_value;
		retval = du_core->or1k_jtag_read_cpu(&or1k->jtag, GROUP0 + 16 /* NPC */, 1, &reg_value);
		if (retval != ERROR_OK) {
			LOG_ERROR("Error while reading NPC");
			return retval;
		}

		samples[sample_count++] = reg_value;

		gettimeofday(&now, NULL);
		if ((sample_count >= max_num_samples) ||
			((now.tv_sec >= timeout.tv_sec) && (now.tv_usec >= timeout.tv_usec))) {
			LOG_INFO("Profiling completed. %" PRIu32 " samples.", sample_count);
			break;
		}
	}

	*num_samples = sample_count;
	return retval;
}
示例#10
0
static int or1k_remove_breakpoint(struct target *target,
				  struct breakpoint *breakpoint)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);

	LOG_DEBUG("Removing breakpoint: addr 0x%08" TARGET_PRIxADDR ", len %d, type %d, set: %d, id: %" PRId32,
		  breakpoint->address, breakpoint->length, breakpoint->type,
		  breakpoint->set, breakpoint->unique_id);

	/* Only support SW breakpoints for now. */
	if (breakpoint->type == BKPT_HARD)
		LOG_ERROR("HW breakpoints not supported for now. Doing SW breakpoint.");

	/* Replace the removed instruction */
	int retval = du_core->or1k_jtag_write_memory(&or1k->jtag,
					  breakpoint->address,
					  4,
					  1,
					  breakpoint->orig_instr);

	if (retval != ERROR_OK) {
		LOG_ERROR("Error while writing back the instruction at 0x%08" TARGET_PRIxADDR,
			   breakpoint->address);
		return retval;
	}

	/* invalidate instruction cache */
	uint32_t addr = breakpoint->address;
	retval = du_core->or1k_jtag_write_cpu(&or1k->jtag,
			OR1K_ICBIR_CPU_REG_ADD, 1, &addr);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while invalidating the ICACHE");
		return retval;
	}

	return ERROR_OK;
}
示例#11
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_soft_reset_halt(struct target *target)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);

	LOG_DEBUG("-");

	int retval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_STALL);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while stalling the CPU");
		return retval;
	}

	retval = or1k_assert_reset(target);
	if (retval != ERROR_OK)
		return retval;

	retval = or1k_deassert_reset(target);
	if (retval != ERROR_OK)
		return retval;

	return ERROR_OK;
}
示例#12
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_halt(struct target *target)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);

	LOG_DEBUG("target->state: %s",
		  target_state_name(target));

	if (target->state == TARGET_HALTED) {
		LOG_DEBUG("Target was already halted");
		return ERROR_OK;
	}

	if (target->state == TARGET_UNKNOWN)
		LOG_WARNING("Target was in unknown state when halt was requested");

	if (target->state == TARGET_RESET) {
		if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) &&
		    jtag_get_srst()) {
			LOG_ERROR("Can't request a halt while in reset if nSRST pulls nTRST");
			return ERROR_TARGET_FAILURE;
		} else {
			target->debug_reason = DBG_REASON_DBGRQ;
			return ERROR_OK;
		}
	}

	int retval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_STALL);
	if (retval != ERROR_OK) {
		LOG_ERROR("Impossible to stall the CPU");
		return retval;
	}

	target->debug_reason = DBG_REASON_DBGRQ;

	return ERROR_OK;
}
示例#13
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_restore_context(struct target *target)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	int reg_write = 0;
	int retval;

	LOG_DEBUG("-");

	for (int i = 0; i < OR1KNUMCOREREGS; i++) {
		if (or1k->core_cache->reg_list[i].dirty) {
			or1k_write_core_reg(target, i);

			if (i == OR1K_REG_PPC || i == OR1K_REG_NPC || i == OR1K_REG_SR) {
				retval = du_core->or1k_jtag_write_cpu(&or1k->jtag,
						or1k->arch_info[i].spr_num, 1,
						&or1k->core_regs[i]);
				if (retval != ERROR_OK) {
					LOG_ERROR("Error while restoring context");
					return retval;
				}
			} else
				reg_write = 1;
		}
	}

	if (reg_write) {
		/* read gpr registers at once (but only one time in this loop) */
		retval = or1k_jtag_write_regs(or1k, or1k->core_regs);
		if (retval != ERROR_OK) {
			LOG_ERROR("Error while restoring context");
			return retval;
		}
	}

	return ERROR_OK;
}
示例#14
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_is_cpu_running(struct target *target, int *running)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	int retval;
	int tries = 0;
	const int RETRIES_MAX = 5;

	/* Have a retry loop to determine of the CPU is running.
	   If target has been hard reset for any reason, it might take a couple
	   of goes before it's ready again.
	*/
	while (tries < RETRIES_MAX) {

		tries++;

		retval = du_core->or1k_is_cpu_running(&or1k->jtag, running);
		if (retval != ERROR_OK) {
			LOG_WARNING("Debug IF CPU control reg read failure.");
			/* Try once to restart the JTAG infrastructure -
			   quite possibly the board has just been reset. */
			LOG_WARNING("Resetting JTAG TAP state and reconnectiong to debug IF.");
			du_core->or1k_jtag_init(&or1k->jtag);

			LOG_WARNING("...attempt %d of %d", tries, RETRIES_MAX);

			alive_sleep(2);

			continue;
		} else
			return ERROR_OK;
	}

	LOG_ERROR("Could not re-establish communication with target");
	return retval;
}
示例#15
0
文件: or1k.c 项目: JasonCC/openocd
static int or1k_resume_or_step(struct target *target, int current,
			       uint32_t address, int handle_breakpoints,
			       int debug_execution, int step)
{
	struct or1k_common *or1k = target_to_or1k(target);
	struct or1k_du *du_core = or1k_to_du(or1k);
	struct breakpoint *breakpoint = NULL;
	uint32_t resume_pc;
	uint32_t debug_reg_list[OR1K_DEBUG_REG_NUM];

	LOG_DEBUG("Addr: 0x%" PRIx32 ", stepping: %s, handle breakpoints %s\n",
		  address, step ? "yes" : "no", handle_breakpoints ? "yes" : "no");

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

	if (!debug_execution)
		target_free_all_working_areas(target);

	/* current ? continue on current pc : continue at <address> */
	if (!current)
		buf_set_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value, 0,
			    32, address);

	int retval = or1k_restore_context(target);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while calling or1k_restore_context");
		return retval;
	}

	/* read debug registers (starting from DMR1 register) */
	retval = du_core->or1k_jtag_read_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD,
					     OR1K_DEBUG_REG_NUM, debug_reg_list);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while reading debug registers");
		return retval;
	}

	/* Clear Debug Reason Register (DRR) */
	debug_reg_list[OR1K_DEBUG_REG_DRR] = 0;

	/* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) */
	debug_reg_list[OR1K_DEBUG_REG_DMR2] &= ~OR1K_DMR2_WGB;
	if (step)
		/* Set the single step trigger in Debug Mode Register 1 (DMR1) */
		debug_reg_list[OR1K_DEBUG_REG_DMR1] |= OR1K_DMR1_ST | OR1K_DMR1_BT;
	else
		/* Clear the single step trigger in Debug Mode Register 1 (DMR1) */
		debug_reg_list[OR1K_DEBUG_REG_DMR1] &= ~(OR1K_DMR1_ST | OR1K_DMR1_BT);

	/* Set traps to be handled by the debug unit in the Debug Stop
	   Register (DSR). Check if we have any software breakpoints in
	   place before setting this value - the kernel, for instance,
	   relies on l.trap instructions not stalling the processor ! */
	if (is_any_soft_breakpoint(target) == true)
		debug_reg_list[OR1K_DEBUG_REG_DSR] |= OR1K_DSR_TE;

	/* Write debug registers (starting from DMR1 register) */
	retval = du_core->or1k_jtag_write_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD,
					      OR1K_DEBUG_REG_NUM, debug_reg_list);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while writing back debug registers");
		return retval;
	}

	resume_pc = buf_get_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value,
				0, 32);

	/* The front-end may request us not to handle breakpoints */
	if (handle_breakpoints) {
		/* Single step past breakpoint at current address */
		breakpoint = breakpoint_find(target, resume_pc);
		if (breakpoint) {
			LOG_DEBUG("Unset breakpoint at 0x%08" PRIx32, breakpoint->address);
			retval = or1k_remove_breakpoint(target, breakpoint);
			if (retval != ERROR_OK)
				return retval;
		}
	}

	/* Unstall time */
	retval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_UNSTALL);
	if (retval != ERROR_OK) {
		LOG_ERROR("Error while unstalling the CPU");
		return retval;
	}

	if (step)
		target->debug_reason = DBG_REASON_SINGLESTEP;
	else
		target->debug_reason = DBG_REASON_NOTHALTED;

	/* Registers are now invalid */
	register_cache_invalidate(or1k->core_cache);

	if (!debug_execution) {
		target->state = TARGET_RUNNING;
		target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
		LOG_DEBUG("Target resumed at 0x%08" PRIx32, resume_pc);
	} else {
		target->state = TARGET_DEBUG_RUNNING;
		target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
		LOG_DEBUG("Target debug resumed at 0x%08" PRIx32, resume_pc);
	}

	return ERROR_OK;
}