Exemple #1
0
/* EXPORTED to FA256 */
void arm920t_pre_restore_context(struct target *target)
{
	uint32_t cp15c15;
	struct arm920t_common *arm920t = target_to_arm920(target);

	/* restore i/d fault status and address register */
	arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
	arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
	arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
	arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);

	/* read-modify-write CP15 test state register
	* to reenable I/D-cache linefills */
	if (arm920t->preserve_cache) {
		arm920t_read_cp15_physical(target,
			CP15PHYS_TESTSTATE, &cp15c15);
		jtag_execute_queue();
		cp15c15 &= ~0x600U;
		arm920t_write_cp15_physical(target,
			CP15PHYS_TESTSTATE, cp15c15);
	}
}
Exemple #2
0
static int arm920t_mcr(struct target *target, int cpnum,
	uint32_t op1, uint32_t op2,
	uint32_t CRn, uint32_t CRm,
	uint32_t value)
{
	if (cpnum != 15) {
		LOG_ERROR("Only cp15 is supported");
		return ERROR_FAIL;
	}

	/* write "from" r0 */
	return arm920t_write_cp15_interpreted(target,
		ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2),
		0, value);
}
Exemple #3
0
/** Writes a buffer, in the specified word size, with current MMU settings. */
int arm920t_write_memory(struct target *target, uint32_t address,
		uint32_t size, uint32_t count, uint8_t *buffer)
{
	int retval;
	const uint32_t cache_mask = ~0x1f; /* cache line size : 32 byte */
	struct arm920t_common *arm920t = target_to_arm920(target);

	/* FIX!!!! this should be cleaned up and made much more general. The
	 * plan is to write up and test on arm920t specifically and
	 * then generalize and clean up afterwards.
	 *
	 * Also it should be moved to the callbacks that handle breakpoints
	 * specifically and not the generic memory write fn's. See XScale code.
	 */
	if (arm920t->armv4_5_mmu.mmu_enabled && (count == 1) &&
			((size==2) || (size==4)))
	{
		/* special case the handling of single word writes to
		 * bypass MMU, to allow implementation of breakpoints
		 * in memory marked read only
		 * by MMU
		 */
		uint32_t cb;
		uint32_t pa;

		/*
		 * We need physical address and cb
		 */
		retval = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu,
				address, &cb, &pa);
		if (retval != ERROR_OK)
			return retval;

		if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
		{
			if (cb & 0x1)
			{
				LOG_DEBUG("D-Cache buffered, "
						"drain write buffer");
				/*
				 * Buffered ?
				 * Drain write buffer - MCR p15,0,Rd,c7,c10,4
				 */

				retval = arm920t_write_cp15_interpreted(target,
					ARMV4_5_MCR(15, 0, 0, 7, 10, 4),
					0x0, 0);
				if (retval != ERROR_OK)
					return retval;
			}

			if (cb == 0x3)
			{
				/*
				 * Write back memory ? -> clean cache
				 *
				 * There is no way to clean cache lines using
				 * cp15 scan chain, so copy the full cache
				 * line from cache to physical memory.
				 */
				uint8_t data[32];

				LOG_DEBUG("D-Cache in 'write back' mode, "
						"flush cache line");

				retval = target_read_memory(target,
						address & cache_mask, 1,
						sizeof(data), &data[0]);
				if (retval != ERROR_OK)
					return retval;

				retval = armv4_5_mmu_write_physical(target,
						&arm920t->armv4_5_mmu,
						pa & cache_mask, 1,
						sizeof(data), &data[0]);
				if (retval != ERROR_OK)
					return retval;
			}

			/* Cached ? */
			if (cb & 0x2)
			{
				/*
				 * Cached ? -> Invalidate data cache using MVA
				 *
				 * MCR p15,0,Rd,c7,c6,1
				 */
				LOG_DEBUG("D-Cache enabled, "
					"invalidate cache line");

				retval = arm920t_write_cp15_interpreted(target,
					ARMV4_5_MCR(15, 0, 0, 7, 6, 1), 0x0,
					address & cache_mask);
				if (retval != ERROR_OK)
					return retval;
			}
		}

		/* write directly to physical memory,
		 * bypassing any read only MMU bits, etc.
		 */
		retval = armv4_5_mmu_write_physical(target,
				&arm920t->armv4_5_mmu, pa, size,
				count, buffer);
		if (retval != ERROR_OK)
			return retval;
	} else
	{
		if ((retval = arm7_9_write_memory(target, address,
					size, count, buffer)) != ERROR_OK)
			return retval;
	}

	/* If ICache is enabled, we have to invalidate affected ICache lines
	 * the DCache is forced to write-through,
	 * so we don't have to clean it here
	 */
	if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
	{
		if (count <= 1)
		{
			/* invalidate ICache single entry with MVA
			 *   mcr	15, 0, r0, cr7, cr5, {1}
			 */
			LOG_DEBUG("I-Cache enabled, "
				"invalidating affected I-Cache line");
			retval = arm920t_write_cp15_interpreted(target,
					ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
					0x0, address & cache_mask);
			if (retval != ERROR_OK)
				return retval;
		}
		else
		{
			/* invalidate ICache
			 *  mcr	15, 0, r0, cr7, cr5, {0}
			 */
			retval = arm920t_write_cp15_interpreted(target,
					ARMV4_5_MCR(15, 0, 0, 7, 5, 0),
					0x0, 0x0);
			if (retval != ERROR_OK)
				return retval;
		}
	}

	return ERROR_OK;
}