Esempio n. 1
0
int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
{
	switch (size)
	{
		case 1:
			return mips32_pracc_write_mem8(ejtag_info, addr, count, (uint8_t*)buf);
		case 2:
			return mips32_pracc_write_mem16(ejtag_info, addr, count,(uint16_t*)buf);
		case 4:
			if (count == 1)
				return mips32_pracc_write_u32(ejtag_info, addr, (uint32_t*)buf);
			else
				return mips32_pracc_write_mem32(ejtag_info, addr, count, (uint32_t*)buf);
	}

	return ERROR_OK;
}
Esempio n. 2
0
int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
{
	int retval;

	switch (size) {
		case 1:
			retval = mips32_pracc_write_mem8(ejtag_info, addr, count, (uint8_t *)buf);
			break;
		case 2:
			retval = mips32_pracc_write_mem16(ejtag_info, addr, count, (uint16_t *)buf);
			break;
		case 4:
			if (count == 1)
				retval = mips32_pracc_write_u32(ejtag_info, addr, (uint32_t *)buf);
			else
				retval = mips32_pracc_write_mem32(ejtag_info, addr, count, (uint32_t *)buf);
			break;
		default:
			retval = ERROR_FAIL;
	}

	/**
	 * If we are in the cachable regoion and cache is activated,
	 * we must clean D$ + invalidate I$ after we did the write,
	 * so that changes do not continue to live only in D$, but to be
	 * replicated in I$ also (maybe we wrote the istructions)
	 */
	uint32_t conf = 0;
	int cached = 0;

	mips32_cp0_read(ejtag_info, &conf, 16, 0);

	switch (KSEGX(addr)) {
		case KUSEG:
			cached = (conf & MIPS32_CONFIG0_KU_MASK) >> MIPS32_CONFIG0_KU_SHIFT;
			break;
		case KSEG0:
			cached = (conf & MIPS32_CONFIG0_K0_MASK) >> MIPS32_CONFIG0_K0_SHIFT;
			break;
		case KSEG1:
			/* uncachable segment - nothing to do */
			break;
		case KSEG2:
		case KSEG3:
			cached = (conf & MIPS32_CONFIG0_K23_MASK) >> MIPS32_CONFIG0_K23_SHIFT;
			break;
		default:
			/* what ? */
			break;
	}

	/**
	 * Check cachablitiy bits coherency algorithm -
	 * is the region cacheable or uncached.
	 * If cacheable we have to synchronize the cache
	 */
	if (cached == 0x3) {
		uint32_t start_addr, end_addr;
		uint32_t rel;

		start_addr = addr;
		end_addr = addr + count * size;

		/** select cache synchronisation mechanism based on Architecture Release */
		rel = (conf & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT;
		switch (rel) {
			case MIPS32_ARCH_REL1:
				/* MIPS32/64 Release 1 - we must use cache instruction */
				mips32_pracc_clean_invalidate_cache(ejtag_info, start_addr, end_addr);
				break;
			case MIPS32_ARCH_REL2:
				/* MIPS32/64 Release 2 - we can use synci instruction */
				mips32_pracc_sync_cache(ejtag_info, start_addr, end_addr);
				break;
			default:
				/* what ? */
				break;
		}
	}
Esempio n. 3
0
/* fastdata upload/download requires an initialized working area
 * to load the download code; it should not be called otherwise
 * fetch order from the fastdata area
 * 1. start addr
 * 2. end addr
 * 3. data ...
 */
int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_area *source,
								int write, uint32_t addr, int count, uint32_t *buf)
{
	uint32_t handler_code[] = {
		/* caution when editing, table is modified below */
		/* r15 points to the start of this code */
		MIPS32_SW(8,MIPS32_FASTDATA_HANDLER_SIZE - 4,15),
		MIPS32_SW(9,MIPS32_FASTDATA_HANDLER_SIZE - 8,15),
		MIPS32_SW(10,MIPS32_FASTDATA_HANDLER_SIZE - 12,15),
		MIPS32_SW(11,MIPS32_FASTDATA_HANDLER_SIZE - 16,15),
		/* start of fastdata area in t0 */
		MIPS32_LUI(8,UPPER16(MIPS32_PRACC_FASTDATA_AREA)),
		MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_FASTDATA_AREA)),
		MIPS32_LW(9,0,8),								/* start addr in t1 */
		MIPS32_LW(10,0,8),								/* end addr to t2 */
														/* loop: */
		/* 8 */ MIPS32_LW(11,0,0),						/* lw t3,[t8 | r9] */
		/* 9 */ MIPS32_SW(11,0,0),						/* sw t3,[r9 | r8] */
		MIPS32_BNE(10,9,NEG16(3)),						/* bne $t2,t1,loop */
		MIPS32_ADDI(9,9,4),								/* addi t1,t1,4 */

		MIPS32_LW(8,MIPS32_FASTDATA_HANDLER_SIZE - 4,15),
		MIPS32_LW(9,MIPS32_FASTDATA_HANDLER_SIZE - 8,15),
		MIPS32_LW(10,MIPS32_FASTDATA_HANDLER_SIZE - 12,15),
		MIPS32_LW(11,MIPS32_FASTDATA_HANDLER_SIZE - 16,15),

		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_TEXT)),
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_TEXT)),
		MIPS32_JR(15),									/* jr start */
		MIPS32_MFC0(15,31,0),							/* move COP0 DeSave to $15 */
	};

	uint32_t jmp_code[] = {
		MIPS32_MTC0(15,31,0),			/* move $15 to COP0 DeSave */
		/* 1 */ MIPS32_LUI(15,0),		/* addr of working area added below */
		/* 2 */ MIPS32_ORI(15,15,0),	/* addr of working area added below */
		MIPS32_JR(15),					/* jump to ram program */
		MIPS32_NOP,
	};

	int retval, i;
	uint32_t val, ejtag_ctrl, address;

	if (source->size < MIPS32_FASTDATA_HANDLER_SIZE)
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;

	if (write)
	{
		handler_code[8] = MIPS32_LW(11,0,8);	/* load data from probe at fastdata area */
		handler_code[9] = MIPS32_SW(11,0,9);	/* store data to RAM @ r9 */
	}
	else
	{
		handler_code[8] = MIPS32_LW(11,0,9);	/* load data from RAM @ r9 */
		handler_code[9] = MIPS32_SW(11,0,8);	/* store data to probe at fastdata area */
	}

	/* write program into RAM */
	mips32_pracc_write_mem32(ejtag_info, source->address, ARRAY_SIZE(handler_code), handler_code);

	LOG_DEBUG("%s using 0x%.8" PRIx32 " for write handler\n", __func__, source->address);

	jmp_code[1] |= UPPER16(source->address);
	jmp_code[2] |= LOWER16(source->address);

	for (i = 0; i < (int) ARRAY_SIZE(jmp_code); i++)
	{
		if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
			return retval;

		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
		mips_ejtag_drscan_32(ejtag_info, &jmp_code[i]);

		/* Clear the access pending bit (let the processor eat!) */
		ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
		mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
	}

	if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
		return retval;

	/* next fetch to dmseg should be in FASTDATA_AREA, check */
	address = 0;
	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
	mips_ejtag_drscan_32(ejtag_info, &address);

	if (address != MIPS32_PRACC_FASTDATA_AREA)
		return ERROR_FAIL;

	/* Send the load start address */
	val = addr;
	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA, NULL);
	mips_ejtag_fastdata_scan(ejtag_info, 1, &val);

	/* Send the load end address */
	val = addr + (count - 1) * 4;
	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA, NULL);
	mips_ejtag_fastdata_scan(ejtag_info, 1, &val);

	for (i = 0; i < count; i++)
	{
		/* Send the data out using fastdata (clears the access pending bit) */
		if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write, buf++)) != ERROR_OK)
			return retval;
	}

	if ((retval = jtag_execute_queue()) != ERROR_OK)
	{
		LOG_ERROR("fastdata load failed");
		return retval;
	}

	if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
		return retval;

	address = 0;
	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
	mips_ejtag_drscan_32(ejtag_info, &address);

	if (address != MIPS32_PRACC_TEXT)
		LOG_ERROR("mini program did not return to start\n");

	return retval;
}