Esempio n. 1
0
static int arm720t_write_phys_memory(struct target *target,
		uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
	struct arm720t_common *arm720t = target_to_arm720(target);

	return armv4_5_mmu_write_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer);
}
Esempio n. 2
0
/** Writes a buffer, in the specified word size, with current MMU settings. */
int arm926ejs_write_memory(struct target *target, uint32_t address,
		uint32_t size, uint32_t count, const uint8_t *buffer)
{
	int retval;
	struct arm926ejs_common *arm926ejs = target_to_arm926(target);

	/* FIX!!!! this should be cleaned up and made much more general. The
	 * plan is to write up and test on arm926ejs 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 (arm926ejs->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 */
		if (arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {
			/* flush and invalidate data cache
			 *
			 * MCR p15,0,p,c7,c10,1 - clean cache line using virtual address
			 *
			 */
			retval = arm926ejs->write_cp15(target, 0, 1, 7, 10, address&~0x3);
			if (retval != ERROR_OK)
				return retval;
		}

		uint32_t pa;
		retval = target->type->virt2phys(target, address, &pa);
		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, &arm926ejs->armv4_5_mmu, pa, size, count, buffer);
		if (retval != ERROR_OK)
			return retval;
	} else {
		retval = arm7_9_write_memory(target, address, size, count, buffer);
		if (retval != 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 (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled) {
		if (count <= 1) {
			/* invalidate ICache single entry with MVA */
			arm926ejs->write_cp15(target, 0, 1, 7, 5, address);
		} else {
			/* invalidate ICache */
			arm926ejs->write_cp15(target, 0, 0, 7, 5, address);
		}
	}

	return retval;
}
Esempio n. 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;
}