Backing out that change, will break non-MMU execution. Baaad....
I tried to copy & paste the solution from 926ejs which also supports
writing breakpoints to memory marked as read only by the MMU.
Bonus!
I don't have hardware to test on.
If it works it fixes a bug as well as adds a new feature.
--
Øyvind Harboe
Visit us at Embedded World, March 2nd-4th. IS2T's stand, HALL 10 - 118
http://www.zylin.com/events_embeddedworld.html
US toll free 1-866-980-3434 / International +47 51 63 25 00
http://www.zylin.com/zy1000.html
ARM7 ARM9 ARM11 XScale Cortex
JTAG debugger and flash programmer
diff --git a/src/target/arm920t.c b/src/target/arm920t.c
index e0b1c70..70792b8 100644
--- a/src/target/arm920t.c
+++ b/src/target/arm920t.c
@@ -510,37 +510,73 @@ static int arm920t_write_phys_memory(struct target
*target,
/** Writes a buffer, in the specified word size, with current MMU settings. */
-int arm920t_write_memory(struct target *target, uint32_t address, uint32_t
size, uint32_t count, uint8_t *buffer)
+int arm920t_write_memory(struct target *target, uint32_t address,
+ uint32_t size, uint32_t count, uint8_t *buffer)
{
int retval;
+ struct arm920t_common *arm920t = target_to_arm920(target);
- if ((retval = arm7_9_write_memory(target, address, size, count,
buffer)) != ERROR_OK)
- return retval;
-
- /* This fn is used to write breakpoints, so we need to make sure
- * that the data cache is flushed and the instruction cache is
- * invalidated
- */
- if (((size == 4) || (size == 2)) && (count == 1))
+ /* FIX!!!! this should be cleaned up and made much more general. The
+ * plan is to write up and test on arm920t specifically and
+ * then generalize and clean up afterwards. */
+ if (arm920t->armv4_5_mmu.mmu_enabled && (count == 1) && ((size==2) ||
(size==4)))
{
- struct arm920t_common *arm920t = target_to_arm920(target);
-
+ /* special case the handling of single word writes to bypass MMU
+ * to allow implementation of breakpoints in memory marked read
only
+ * by MMU */
if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
{
LOG_DEBUG("D-Cache enabled, flush and invalidate cache
line");
- /* MCR p15,0,Rd,c7,c10,2 */
- retval = arm920t_write_cp15_interpreted(target,
0xee070f5e, 0x0, address);
+
+ /* flush and invalidate data cache
+ *
+ * MCR p15,0,Rd,c7,c14,2 - flush and invalidate cache
line using virtual address
+ *
+ */
+ retval = arm920t_write_cp15_interpreted(target,
0xee070f5e, 0x0, address&~0x3);
if (retval != ERROR_OK)
return retval;
}
- if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
+ uint32_t pa;
+ retval = target->type->virt2phys(target, address, &pa);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* write directly to physical memory bypassing any read only
MMU bits, etc. */
+ retval = armv4_5_mmu_write_physical(target,
&arm920t->armv4_5_mmu, pa, size, count, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ } else
+ {
+ if ((retval = arm7_9_write_memory(target, address, size, count,
buffer)) != ERROR_OK)
+ return retval;
+ }
+
+ /* If ICache is enabled, we have to invalidate affected ICache lines
+ * the DCache is forced to write-through, so we don't have to clean it
here
+ */
+ if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
+ {
+ if (count <= 1)
{
+ /* invalidate ICache single entry with MVA
+ * ee070f35 mcr 15, 0, r0, cr7, cr5, {1}
+ */
LOG_DEBUG("I-Cache enabled, invalidating affected
I-Cache line");
retval = arm920t_write_cp15_interpreted(target,
0xee070f35, 0x0, address);
if (retval != ERROR_OK)
return retval;
}
+ else
+ {
+ /* invalidate ICache
+ * 8: ee070f15 mcr 15, 0, r0, cr7, cr5, {0}
+ * */
+ retval = arm920t_write_cp15_interpreted(target,
0xee070f15, 0x0, address);
+ if (retval != ERROR_OK)
+ return retval;
+ }
}
return retval;
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development