Esempio n. 1
0
/** Execute an instruction via ITR while handing data into the core via DTR.
 *
 *  The executed instruction \em must read data from DTR.
 *
 * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
 *
 * \param arm11		Target state variable.
 * \param opcode	ARM opcode
 * \param data		Data word to be passed to the core via DTR
 *
 */
int arm11_run_instr_data_to_core1(struct arm11_common * arm11, uint32_t opcode, uint32_t data)
{
	return arm11_run_instr_data_to_core(arm11, opcode, &data, 1);
}
Esempio n. 2
0
/*
* no_increment - in the future we may want to be able
* to read/write a range of data to a "port". a "port" is an action on
* read memory address for some peripheral.
*/
static int arm11_write_memory_inner(struct target *target,
		uint32_t address, uint32_t size,
		uint32_t count, const uint8_t *buffer,
		bool no_increment)
{
	int retval;

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

	LOG_DEBUG("ADDR %08" PRIx32 "  SIZE %08" PRIx32 "  COUNT %08" PRIx32 "", address, size, count);

	struct arm11_common *arm11 = target_to_arm11(target);

	retval = arm11_run_instr_data_prepare(arm11);
	if (retval != ERROR_OK)
		return retval;

	/* load r0 with buffer address */
	/* MRC p14,0,r0,c0,c5,0 */
	retval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);
	if (retval != ERROR_OK)
		return retval;

	/* burst writes are not used for single words as those may well be
	 * reset init script writes.
	 *
	 * The other advantage is that as burst writes are default, we'll
	 * now exercise both burst and non-burst code paths with the
	 * default settings, increasing code coverage.
	 */
	bool burst = arm11->memwrite_burst && (count > 1);

	switch (size)
	{
	case 1:
		{
			arm11->arm.core_cache->reg_list[1].dirty = true;

			for (size_t i = 0; i < count; i++)
			{
				/* load r1 from DCC with byte data */
				/* MRC p14,0,r1,c0,c5,0 */
				retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);
				if (retval != ERROR_OK)
					return retval;

				/* write r1 to memory */
				/* strb    r1, [r0], #1 */
				/* strb    r1, [r0] */
				retval = arm11_run_instr_no_data1(arm11,
					!no_increment
						? 0xe4c01001
						: 0xe5c01000);
				if (retval != ERROR_OK)
					return retval;
			}

			break;
		}

	case 2:
		{
			arm11->arm.core_cache->reg_list[1].dirty = true;

			for (size_t i = 0; i < count; i++)
			{
				uint16_t value;
				memcpy(&value, buffer + i * sizeof(uint16_t), sizeof(uint16_t));

				/* load r1 from DCC with halfword data */
				/* MRC p14,0,r1,c0,c5,0 */
				retval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, value);
				if (retval != ERROR_OK)
					return retval;

				/* write r1 to memory */
				/* strh    r1, [r0], #2 */
				/* strh    r1, [r0] */
				retval = arm11_run_instr_no_data1(arm11,
					!no_increment
						? 0xe0c010b2
						: 0xe1c010b0);
				if (retval != ERROR_OK)
					return retval;
			}

			break;
		}

	case 4: {
		/* stream word data through DCC directly to memory */
		/* increment:		STC p14,c5,[R0],#4 */
		/* no increment:	STC p14,c5,[R0]*/
		uint32_t instr = !no_increment ? 0xeca05e01 : 0xed805e00;

		/** \todo TODO: buffer cast to uint32_t* causes alignment warnings */
		uint32_t *words = (uint32_t*)(void *)buffer;

		/* "burst" here just means trusting each instruction executes
		 * fully before we run the next one:  per-word roundtrips, to
		 * check the Ready flag, are not used.
		 */
		if (!burst)
			retval = arm11_run_instr_data_to_core(arm11,
					instr, words, count);
		else
			retval = arm11_run_instr_data_to_core_noack(arm11,
					instr, words, count);
		if (retval != ERROR_OK)
			return retval;

		break;
	}
	}

	/* r0 verification */
	if (!no_increment)
	{
		uint32_t r0;

		/* MCR p14,0,R0,c0,c5,0 */
		retval = arm11_run_instr_data_from_core(arm11, 0xEE000E15, &r0, 1);
		if (retval != ERROR_OK)
			return retval;

		if (address + size * count != r0)
		{
			LOG_ERROR("Data transfer failed. Expected end "
					"address 0x%08x, got 0x%08x",
					(unsigned) (address + size * count),
					(unsigned) r0);

			if (burst)
				LOG_ERROR("use 'arm11 memwrite burst disable' to disable fast burst mode");

			if (arm11->memwrite_error_fatal)
				return ERROR_FAIL;
		}
	}

	return arm11_run_instr_data_finish(arm11);
}
Esempio n. 3
0
static int arm11_dpm_instr_write_data_dcc(struct arm_dpm *dpm,
		uint32_t opcode, uint32_t data)
{
	return arm11_run_instr_data_to_core(dpm_to_arm11(dpm),
			opcode, &data, 1);
}
Esempio n. 4
0
/** Execute an instruction via ITR while handing data into the core via DTR.
 *
 *  The executed instruction \em must read data from DTR.
 *
 * \pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block
 *
 * \param arm11		Target state variable.
 * \param opcode	ARM opcode
 * \param data		Data word to be passed to the core via DTR
 *
 */
void arm11_run_instr_data_to_core1(arm11_common_t * arm11, u32 opcode, u32 data)
{
    arm11_run_instr_data_to_core(arm11, opcode, &data, 1);
}