[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openocd-development
Subject:    [OpenOCD-devel] [PATCH]: 085436d Speed up pracc code with ftdi based adapters.
From:       gerrit () openocd ! zylin ! com
Date:       2012-07-22 22:40:38
Message-ID: 20120722224039.08CA024AA3 () openocd ! zylin ! com
[Download RAW message or body]

This is an automated email from Gerrit.

Salvador Arroyo (sarroyofdez@yahoo.es) just uploaded a new patch set to Gerrit, which \
you can find at http://openocd.zylin.com/759

-- gerrit

commit 085436ded71fd81f1e3b7ba0ccd62e83dcbff71d
Author: Salvador Arroyo <sarroyofdez@yahoo.es>
Date:   Sun Jul 22 23:03:00 2012 +0200

    Speed up pracc code with ftdi based adapters.
    
    The register "all" defined in ejtage specifications
    MD00047 (Mandatory) provides the way to transfer
    the contents of control, address an data register
    in one scan.
    For usb dump type adapters this type of scan is
    more efficient.
    The functions mips_ejtag_drscan_96() and
    mips_ejtag_drscan_96_out() are added to scan register all.
    The function wait_for_pracc_rw_all() is added to pass all
    the values scanned.
    Pracc code functions mips32_pracc_exec(), mips32_pracc_exec_read()
    and mips32_pracc_exec_write() are modified to use those functions.
    This code now works sligthly over 2x faster.
    
    Surprisingly in a pic32mx_1_2 variant, now it is possible to
    scan at any frequency, tested up to 15Mhz.
    
    Change-Id: I40db8c23d87d7e32af6dde8942526986fedaea6e
    Signed-off-by: Salvador Arroyo <sarroyofdez@yahoo.es>

diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index d657b98..abd658c 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -146,6 +146,35 @@ static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, \
uint32_t *ctrl)  return ERROR_OK;
 }
 
+static int wait_for_pracc_rw_all(struct mips_ejtag *ejtag_info, uint32_t *ctrl, \
uint32_t *data, uint32_t *addr) +{
+	uint32_t ejtag_ctrl;
+	long long then = timeval_ms();
+	int timeout;
+	int retval;
+
+	/* wait for the PrAcc to become "1" */
+	ejtag_ctrl = ejtag_info->ejtag_ctrl;
+
+	while (1) {
+		retval = mips_ejtag_drscan_96(ejtag_info, &ejtag_ctrl, data, addr);
+		if (retval != ERROR_OK)
+			return retval;
+
+		if (ejtag_ctrl & EJTAG_CTRL_PRACC)
+			break;
+
+		timeout = timeval_ms() - then;
+		if (timeout > 1000) {
+			LOG_DEBUG("DEBUGMODULE: No memory access in progress!");
+			return ERROR_JTAG_DEVICE_ERROR;
+		}
+	}
+
+	*ctrl = ejtag_ctrl;
+	return ERROR_OK;
+}
+
 static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t \
address)  {
 	struct mips_ejtag *ejtag_info = ctx->ejtag_info;
@@ -153,20 +182,25 @@ static int mips32_pracc_exec_read(struct mips32_pracc_context \
*ctx, uint32_t add  uint32_t ejtag_ctrl, data;
 
 	if ((address >= MIPS32_PRACC_PARAM_IN)
-		&& (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) {
+		&& (address < MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) {
 		offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
 		data = ctx->local_iparam[offset];
 	} else if ((address >= MIPS32_PRACC_PARAM_OUT)
-		&& (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) {
+		&& (address < MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) {
 		offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
 		data = ctx->local_oparam[offset];
 	} else if ((address >= MIPS32_PRACC_TEXT)
-		&& (address <= MIPS32_PRACC_TEXT + ctx->code_len * 4)) {
+		&& (address < MIPS32_PRACC_TEXT + ctx->code_len * 4)) {
 		offset = (address - MIPS32_PRACC_TEXT) / 4;
 		data = ctx->code[offset];
 	} else if (address == MIPS32_PRACC_STACK) {
 		/* save to our debug stack */
+		if (ctx->stack_offset <= 0) {
+			LOG_ERROR("Error: Pracc stack out of bounds");
+			return ERROR_JTAG_DEVICE_ERROR;
+		}
 		data = ctx->stack[--ctx->stack_offset];
+
 	} else {
 		/* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
 		 * to start of debug vector */
@@ -175,50 +209,47 @@ static int mips32_pracc_exec_read(struct mips32_pracc_context \
*ctx, uint32_t add  return ERROR_JTAG_DEVICE_ERROR;
 	}
 
-	/* Send the data out */
-	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
-	mips_ejtag_drscan_32_out(ctx->ejtag_info, data);
-
-	/* Clear the access pending bit (let the processor eat!) */
+	/* Send the data out and clear the access pending bit (let the processor eat!) */
 	ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
-	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
-	mips_ejtag_drscan_32_out(ctx->ejtag_info, ejtag_ctrl);
+	mips_ejtag_drscan_96_out(ctx->ejtag_info, ejtag_ctrl, data);
 
 	return jtag_execute_queue();
 }
 
-static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t \
address) +static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, \
uint32_t data, uint32_t address)  {
-	uint32_t ejtag_ctrl, data;
+	uint32_t ejtag_ctrl;
 	int offset;
 	struct mips_ejtag *ejtag_info = ctx->ejtag_info;
 	int retval;
 
-	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
-	retval = mips_ejtag_drscan_32(ctx->ejtag_info, &data);
-	if (retval != ERROR_OK)
-		return retval;
-
 	/* Clear access pending bit */
 	ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
 	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
 	mips_ejtag_drscan_32_out(ctx->ejtag_info, ejtag_ctrl);
 
+	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_ALL);
+
 	retval = jtag_execute_queue();
 	if (retval != ERROR_OK)
 		return retval;
 
 	if ((address >= MIPS32_PRACC_PARAM_IN)
-		&& (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) {
+		&& (address < MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4)) {
 		offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
 		ctx->local_iparam[offset] = data;
 	} else if ((address >= MIPS32_PRACC_PARAM_OUT)
-		&& (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) {
+		&& (address < MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4)) {
 		offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
 		ctx->local_oparam[offset] = data;
 	} else if (address == MIPS32_PRACC_STACK) {
 		/* save data onto our stack */
+		if (ctx->stack_offset >= 32) {
+			LOG_ERROR("Error: Pracc stack out of bounds");
+			return ERROR_JTAG_DEVICE_ERROR;
+		}
 		ctx->stack[ctx->stack_offset++] = data;
+
 	} else {
 		LOG_ERROR("Error writing unexpected address 0x%8.8" PRIx32 "", address);
 		return ERROR_JTAG_DEVICE_ERROR;
@@ -231,7 +262,8 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int \
code_len, const uint32_  int num_param_in, uint32_t *param_in, int num_param_out, \
uint32_t *param_out, int cycle)  {
 	uint32_t ejtag_ctrl;
-	uint32_t address, data;
+	uint32_t address;
+	uint32_t data;
 	struct mips32_pracc_context ctx;
 	int retval;
 	int pass = 0;
@@ -245,20 +277,17 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int \
code_len, const uint32_  ctx.ejtag_info = ejtag_info;
 	ctx.stack_offset = 0;
 
-	while (1) {
-		retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
-		if (retval != ERROR_OK)
-			return retval;
+	mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);
 
-		address = data = 0;
-		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
-		retval = mips_ejtag_drscan_32(ejtag_info, &address);
+	while (1) {
+		data = 0;
+		retval = wait_for_pracc_rw_all(ejtag_info, &ejtag_ctrl, &data, &address);
 		if (retval != ERROR_OK)
 			return retval;
 
 		/* Check for read or write */
 		if (ejtag_ctrl & EJTAG_CTRL_PRNW) {
-			retval = mips32_pracc_exec_write(&ctx, address);
+			retval = mips32_pracc_exec_write(&ctx, data, address);
 			if (retval != ERROR_OK)
 				return retval;
 		} else {
@@ -828,6 +857,8 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, \
                uint32_t addr, int siz
 	 */
 	uint32_t conf = 0;
 	int cached = 0;
+	if (KSEGX(addr) == KSEG1 || (addr >= 0xff200000 && addr <= 0xff3fffff))
+		return retval;
 
 	mips32_cp0_read(ejtag_info, &conf, 16, 0);
 
@@ -838,9 +869,6 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, \
uint32_t addr, int siz  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;
diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c
index 9114f8c..f500ee9 100644
--- a/src/target/mips_ejtag.c
+++ b/src/target/mips_ejtag.c
@@ -99,6 +99,64 @@ static int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info, \
uint32_t *impco  return ERROR_OK;
 }
 
+/* Control, data and address */
+int mips_ejtag_drscan_96(struct mips_ejtag *ejtag_info, uint32_t *ctrl, uint32_t \
*data, uint32_t *addr) +{
+	struct jtag_tap *tap;
+	tap  = ejtag_info->tap;
+	assert(tap != NULL);
+
+	struct scan_field field;
+	uint8_t t[12], r[12];
+	int retval;
+
+	field.num_bits = 96;
+	field.out_value = t;
+	field.in_value = r;
+
+	/* Out value for address, 0 */
+	buf_set_u32(t, 0, 32, *ctrl);
+	buf_set_u32(t + 4, 0, 32, *data);
+	buf_set_u32(t + 8, 0, 32, 0);
+
+	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
+
+	retval = jtag_execute_queue();
+	if (retval != ERROR_OK) {
+		LOG_ERROR("register read_all failed");
+		return retval;
+	}
+
+	*ctrl = buf_get_u32(r, 0, 32);
+	*data = buf_get_u32(r + 4, 0, 32);
+	*addr = buf_get_u32(r + 8, 0, 32);
+
+	keep_alive();
+
+	return ERROR_OK;
+}
+
+void mips_ejtag_drscan_96_out(struct mips_ejtag *ejtag_info, uint32_t ctrl, uint32_t \
data) +{
+	uint8_t t[12];
+	struct jtag_tap *tap;
+	tap  = ejtag_info->tap;
+	assert(tap != NULL);
+
+	struct scan_field field;
+
+	field.num_bits = 96;
+	field.out_value = t;
+
+	buf_set_u32(t, 0, 32, ctrl);
+	buf_set_u32(t + 4, 0, 32, data);
+	buf_set_u32(t + 8, 0, 32, 0);
+
+	field.in_value = NULL;
+
+	jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
+}
+
 int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)
 {
 	struct jtag_tap *tap;
diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h
index be2af27..7e78238 100644
--- a/src/target/mips_ejtag.h
+++ b/src/target/mips_ejtag.h
@@ -135,6 +135,8 @@ void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info,
 int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info);
 int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info);
 int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info, uint32_t *idcode);
+int mips_ejtag_drscan_96(struct mips_ejtag *ejtag_info, uint32_t *ctrl, uint32_t \
*data, uint32_t *addr); +void mips_ejtag_drscan_96_out(struct mips_ejtag *ejtag_info, \
uint32_t ctrl, uint32_t data);  void mips_ejtag_drscan_32_out(struct mips_ejtag \
*ejtag_info, uint32_t data);  int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, \
uint32_t *data);  void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t \
data);

-- 

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic