I have been using OpenOCD for years with various ARM processors.  I just
started a new project for the iMX6, which is an ARM Cortex A9 based
processor.  I upgraded to OpenOCD 0.8.0 (also tried latest sources) to
support the iMX6.  I have successfully gotten a debugging environment setup
for the iMX6 and GDB.

My problem is that when I enable Data Caching on the ARM it
causes weird behavior in GDB.  When I put a breakpoint in GDB the program
will stop, but when I examine memory it all looks incorrect.  Globals and
Stack both seem to be invalid values.  However, the program seems to run OK
otherwise.  Without dcache enabled on the ARM everything runs as expected.

I have done some experiments and found that the problem goes away if I
flush the cache in my code.   The following GDB session shows the effect of
flushing the cache. Note that using the OpenOCD mdw commands shows the same
incorrect values as GDB.

Is there a setting that will allow OpenOCD to read the states of the
variables from DCache or to flush the cache if needed before reading
values?  (this is an ARM Cortex_A9, iMX6SL)


Breakpoint 1, test () at /home/npalmer/Workspace/prowl_on_evk/src/main.c:98
98        char s1 = 4;     <---------- Stack variable
(gdb) n
99        int  s2 = 5;       <---------- Stack variable
(gdb)
104        temp = s1 + g2;
(gdb)
106        arm_dcache_flush();
(gdb) p /c s1
$7 = 128 '\200'
(gdb) p /c s2
$8 = -28 '\344'
(gdb) p /c s3    <------- s3 is a static local variable, so not on stack
and it is OK
$9 = 6 '\006'
(gdb) n               <-------   This executes the arm_dcache_flush();
108        while (1);
(gdb) p /c s1
$10 = 4 '\004'     <-------  Values are now correct
(gdb) p /c s2
$11 = 5 '\005'
(gdb) p /c s3
$12 = 6 '\006'

I verified that it was a caching problem by patching openocd to flush the
cache when GDB breaks (cortex_a_post_debug_entry) and it works as expected,
however this may not be optimal as it takes longer to step through the code
now.  I attached the patch to this email.

Is this a bad/good idea? Is there a better solution already built in to
OpenOCD that I
am missing?

Thanks!
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 7d58ab3..a2fb0a8 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -1257,6 +1257,12 @@ static int cortex_a_post_debug_entry(struct target *target)
 		(cortex_a->cp15_control_reg & 0x1000U) ? 1 : 0;
 	cortex_a->curr_mode = armv7a->arm.core_mode;
 
+	if (armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) {
+		/* flush data cache armv7 function to be called */
+		if (armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache)
+			armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache(target);
+	}
+
 	return ERROR_OK;
 }
 
------------------------------------------------------------------------------
Infragistics Professional
Build stunning WinForms apps today!
Reboot your WinForms applications with our WinForms controls. 
Build a bridge from your legacy apps to the future.
http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to