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

List:       openocd-development
Subject:    [OpenOCD-devel] [PATCH]: c354d3b mips: 24kc workaround.
From:       gerrit () openocd ! zylin ! com
Date:       2013-11-12 18:43:24
Message-ID: 20131112184324.9D295242C9 () 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/1807

-- gerrit

commit c354d3bf1ebb2ed1d500e557ccbe1d3345679d5d
Author: Salvador Arroyo <sarroyofdez@yahoo.es>
Date:   Tue Nov 12 19:34:58 2013 +0100

    mips: 24kc workaround.
    
    If the core is halted in the delay slot of a branch and after executing
    the first instruction in debug mode, sometimes, it jumps back to pracc text.
    This problem can only be seen in queued mode, is detected as an
    unexpected jump to 0xff200200 and after this fail any other function fails due to
    unexpected start address.
    In legacy mode fails silently, is seen as a second pass through pracc text
    and exits without any error after executing the first instruction.
    The function mips32_pracc_clean_text_jump() is introduced to put
    pracc access in a known state after any fail.
    Similar problem can be shown with the command "mips32 cp0 16  0xffffffff"
    for example. Due to the lack of filtering ends triggering a debug mode
    exception (reserved instruction).
    Probably this is not a problem for m4k but in 24kc a simple
    mdw from kseg 2-3 may trigger a tlb related exception.
    
    Change-Id: I1a568dd9d69918cf2c7b329f206692b3c296da21
    Signed-off-by: Salvador Arroyo <sarroyofdez@yahoo.es>

diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index d0ecba2..45f4ecf 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -128,6 +128,31 @@ static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, \
uint32_t *ctrl)  return ERROR_OK;
 }
 
+int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info)
+{
+	uint32_t jt_code = MIPS32_J((0x0FFFFFFF & MIPS32_PRACC_TEXT) >> 2);
+	/* Write 3 0/nops to clean pipeline before a J jump to pracc text, nop in delay \
slot */ +
+	for (int i = 0; i != 5; i++) {
+		/* Wait for pracc */
+		uint32_t ctrl;
+		int retval = wait_for_pracc_rw(ejtag_info, &ctrl);
+		if (retval != ERROR_OK)
+			return retval;
+
+		/* Data or instruction out */
+		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
+		uint32_t data = (i == 3) ? jt_code : 0;
+		mips_ejtag_drscan_32_out(ejtag_info, data);
+
+		/* finish pa */
+		ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
+		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
+		mips_ejtag_drscan_32_out(ejtag_info, ctrl);
+	}
+	return jtag_execute_queue();
+}
+
 static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t \
address)  {
 	struct mips_ejtag *ejtag_info = ctx->ejtag_info;
@@ -398,6 +423,8 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct \
pracc_queue_in  }
 exit:
 	free(scan_in);
+	if (retval != ERROR_OK)
+		mips32_pracc_clean_text_jump(ejtag_info);
 	return retval;
 }
 
diff --git a/src/target/mips32_pracc.h b/src/target/mips32_pracc.h
index 4b49855..4b9e0e3 100644
--- a/src/target/mips32_pracc.h
+++ b/src/target/mips32_pracc.h
@@ -58,6 +58,8 @@ struct pracc_queue_info {
 	int store_count;
 	uint32_t *pracc_list;	/* Code and store addresses */
 };
+
+int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info);
 void pracc_queue_init(struct pracc_queue_info *ctx);
 void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr);
 void pracc_queue_free(struct pracc_queue_info *ctx);
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 49edad1..bb0ab23 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -95,6 +95,8 @@ static int mips_m4k_debug_entry(struct target *target)
 	struct mips32_common *mips32 = target_to_mips32(target);
 	struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
 
+	mips32_pracc_clean_text_jump(ejtag_info);
+
 	mips32_save_context(target);
 
 	/* make sure stepping disabled, SSt bit in CP0 debug register cleared */

-- 

------------------------------------------------------------------------------
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
_______________________________________________
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