예제 #1
0
/* Set (to enable) or clear (to disable stepping) the SSt bit (bit 8) in Cp0 Debug reg (reg 23, sel 0) */
int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
{
	struct pracc_queue_info ctx = {.max_code = 7};
	pracc_queue_init(&ctx);
	if (ctx.retval != ERROR_OK)
		goto exit;

	pracc_add(&ctx, 0, MIPS32_MFC0(8, 23, 0));			/* move COP0 Debug to $8 */
	pracc_add(&ctx, 0, MIPS32_ORI(8, 8, 0x0100));			/* set SSt bit in debug reg */
	if (!enable_step)
		pracc_add(&ctx, 0, MIPS32_XORI(8, 8, 0x0100));		/* clear SSt bit in debug reg */

	pracc_add(&ctx, 0, MIPS32_MTC0(8, 23, 0));			/* move $8 to COP0 Debug */
	pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(ejtag_info->reg8)));		/* restore upper 16 bits  of $8 */
	pracc_add(&ctx, 0, MIPS32_B(NEG16((ctx.code_count + 1))));			/* jump to start */
	pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8)));	/* restore lower 16 bits of $8 */

	ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
exit:
	pracc_queue_free(&ctx);
	return ctx.retval;
}

/*
 * Disable memory protection for 0xFF20.0000–0xFF3F.FFFF
 * It is needed by EJTAG 1.5-2.0, especially for BMIPS CPUs
 * For example bcm7401 and others. At leas on some
 * CPUs, DebugMode wont start if this bit is not removed.
 */
static int disable_dcr_mp(struct mips_ejtag *ejtag_info)
{
	uint32_t dcr;
	int retval;

	retval = mips32_dmaacc_read_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr);
	if (retval != ERROR_OK)
		goto error;

	dcr &= ~EJTAG_DCR_MP;
	retval = mips32_dmaacc_write_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr);
	if (retval != ERROR_OK)
		goto error;
	return ERROR_OK;
error:
	LOG_ERROR("Failed to remove DCR MPbit!");
	return retval;
}
예제 #2
0
파일: ath79.c 프로젝트: artynet/OpenOCD
static int ath79_spi_bitbang_codegen(struct ath79_flash_bank *ath79_info,
				     struct pracc_queue_info *ctx,
				     uint8_t *data, int len,
				     int partial_xfer)
{
	uint32_t cs_high = ATH79_SPI_CS_ALLHI;
	uint32_t cs_low = ath79_chipselects[ath79_info->chipselect];
	uint32_t clock_high = cs_low | ATH79_SPI_CE_HI;
	uint32_t clock_low = cs_low;
	uint32_t pracc_out = 0;
	uint32_t io_base = ath79_info->io_base;

	const uint32_t preamble1[] = {
		/* $15 = MIPS32_PRACC_BASE_ADDR */
		MIPS32_LUI(0, 15, PRACC_UPPER_BASE_ADDR),
		/* $1 = io_base */
		MIPS32_LUI(0, 1, UPPER16(io_base)),
	};
	ath79_pracc_addn(ctx, preamble1, ARRAY_SIZE(preamble1));
	if (ath79_info->spi.pre_deselect) {
		/* Clear deselect flag so we don't deselect again if
		 * this is a partial xfer.
		 */
		ath79_info->spi.pre_deselect = 0;
		const uint32_t pre_deselect[] = {
			/* [$1 + FS] = 1  (enable flash io register access) */
			MIPS32_LUI(0, 2, UPPER16(1)),
			MIPS32_ORI(0, 2, 2, LOWER16(1)),
			MIPS32_SW(0, 2, ATH79_REG_FS, 1),
			/* deselect flash just in case */
			/* $2 = SPI_CS_DIS */
			MIPS32_LUI(0, 2, UPPER16(cs_high)),
			MIPS32_ORI(0, 2, 2, LOWER16(cs_high)),
			/* [$1 + WRITE] = $2 */
			MIPS32_SW(0, 2, ATH79_REG_WRITE, 1),
		};
		ath79_pracc_addn(ctx, pre_deselect, ARRAY_SIZE(pre_deselect));
	}
	const uint32_t preamble2[] = {
		/* t0 = CLOCK_LOW + 0-bit */
		MIPS32_LUI(0, 8, UPPER16((clock_low + 0))),
		MIPS32_ORI(0, 8, 8, LOWER16((clock_low + 0))),
		/* t1 = CLOCK_LOW + 1-bit */
		MIPS32_LUI(0, 9, UPPER16((clock_low + 1))),
		MIPS32_ORI(0, 9, 9, LOWER16((clock_low + 1))),
		/* t2 = CLOCK_HIGH + 0-bit */
		MIPS32_LUI(0, 10, UPPER16((clock_high + 0))),
		MIPS32_ORI(0, 10, 10, LOWER16((clock_high + 0))),
		/* t3 = CLOCK_HIGH + 1-bit */
		MIPS32_LUI(0, 11, UPPER16((clock_high + 1))),
		MIPS32_ORI(0, 11, 11, LOWER16((clock_high + 1))),
	};
	ath79_pracc_addn(ctx, preamble2, ARRAY_SIZE(preamble2));

	for (int i = 0; i < len; i++) {
		uint8_t x = data[i];

		/* Generate bitbang code for one byte, highest bit first .*/
		for (int j = BITS_PER_BYTE - 1; j >= 0; j--) {
			int bit = ((x >> j) & 1);

			if (bit) {
				/* [$1 + WRITE] = t1 */
				pracc_add(ctx, 0,
					  MIPS32_SW(0, 9, ATH79_REG_WRITE, 1));
				/* [$1 + WRITE] = t3 */
				pracc_add(ctx, 0,
					  MIPS32_SW(0, 11, ATH79_REG_WRITE, 1));
			} else {
				/* [$1 + WRITE] = t0 */
				pracc_add(ctx, 0,
					  MIPS32_SW(0, 8, ATH79_REG_WRITE, 1));
				/* [$1 + WRITE] = t2 */
				pracc_add(ctx, 0,
					  MIPS32_SW(0, 10, ATH79_REG_WRITE, 1));
			}
		}
		if (i % 4 == 3) {
			/* $3 = [$1 + DATA] */
			pracc_add(ctx, 0, MIPS32_LW(0, 3, ATH79_REG_DATA, 1));
			/* [OUTi] = $3 */
			pracc_add(ctx, MIPS32_PRACC_PARAM_OUT + pracc_out,
				  MIPS32_SW(0, 3, PRACC_OUT_OFFSET +
				 pracc_out, 15));
			pracc_out += 4;
		}
	}
	if (len & 3) { /* not a multiple of 4 bytes */
		/* $3 = [$1 + DATA] */
		pracc_add(ctx, 0, MIPS32_LW(0, 3, ATH79_REG_DATA, 1));
		/* [OUTi] = $3 */
		pracc_add(ctx, MIPS32_PRACC_PARAM_OUT + pracc_out,
			  MIPS32_SW(0, 3, PRACC_OUT_OFFSET + pracc_out, 15));
		pracc_out += 4;
	}

	if (ath79_info->spi.post_deselect && !partial_xfer) {
		const uint32_t post_deselect[] = {
			/* $2 = SPI_CS_DIS */
			MIPS32_LUI(0, 2, UPPER16(cs_high)),
			MIPS32_ORI(0, 2, 2, LOWER16(cs_high)),
			/* [$1 + WRITE] = $2 */
			MIPS32_SW(0, 2, ATH79_REG_WRITE, 1),

			/* [$1 + FS] = 0  (disable flash io register access) */
			MIPS32_XORI(0, 2, 2, 0),
			MIPS32_SW(0, 2, ATH79_REG_FS, 1),
		};
		ath79_pracc_addn(ctx, post_deselect, ARRAY_SIZE(post_deselect));
	}

	/* common pracc epilogue */
	/* jump to start */
	pracc_add(ctx, 0, MIPS32_B(0, NEG16(ctx->code_count + 1)));
	/* restore $15 from DeSave */
	pracc_add(ctx, 0, MIPS32_MFC0(0, 15, 31, 0));

	return pracc_out / 4;
}