This is an automated email from Gerrit.

Harishkumar V (harishpres...@gmail.com) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/2428

-- gerrit

commit 4b076b4a2701fe3effaa03c458010e6742edc2dc
Author: HarishKumar <harishpres...@gmail.com>
Date:   Mon Dec 8 21:41:26 2014 +0530

    Cortex-A : Fix invalidating cacheline when MMU is active.
    
    Cortex-A memory write via AHB-AP invalidates instruction/data cacheline 
with physical address when Linux OS is booted on Cortex-A and core is halted 
(MMU enabled). This results in error during memory write request. Cortex-A 
cache operation specification from ARM mentions the usage of modified virtual 
address.
    
    files changed : src/target/cortex_a.c
    Tested with Cortex-A8 based hardware with Linux OS.
    
    Change-Id: I910d8e8ab680f2f685f52d4d4eca97303d5fdb88
    Signed-off-by: HarishKumar <harishpres...@gmail.com>

diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 0393a44..ac5b233 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -74,7 +74,8 @@ static int cortex_a_virt2phys(struct target *target,
        uint32_t virt, uint32_t *phys);
 static int cortex_a_read_apb_ab_memory(struct target *target,
        uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
-
+static int cortex_a_invalidate_instruction_data_cacheline(struct target 
*target,
+       uint32_t address, uint32_t size, uint32_t count);
 
 /*  restore cp15_control_reg at resume */
 static int cortex_a_restore_cp15_control_reg(struct target *target)
@@ -2091,6 +2092,71 @@ error_free_buff_r:
        return ERROR_FAIL;
 }
 
+static int cortex_a_invalidate_instruction_data_cacheline(struct target 
*target,
+       uint32_t address, uint32_t size, uint32_t count)
+{
+       int retval = ERROR_OK;
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+
+       /* REVISIT this op is generic ARMv7-A/R stuff */
+       if (target->state == TARGET_HALTED) {
+               struct arm_dpm *dpm = armv7a->arm.dpm;
+
+               retval = dpm->prepare(dpm);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               /* The Cache handling will NOT work with MMU active, the
+                * wrong addresses will be invalidated!
+                *
+                * For both ICache and DCache, walk all cache lines in the
+                * address range. Cortex-A has fixed 64 byte line length.
+                *
+                * REVISIT per ARMv7, these may trigger watchpoints ...
+                */
+               /* Invalidating physical address while MMU is active
+                * causes issue (Linux OS booted on Cortex-A and core is 
halted).
+                * As per ARMv7 Cortex-A Cache handling,
+                * modified virtual address should be invalidated.
+                */
+               /* invalidate I-Cache */
+               if (armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled) {
+                       /* ICIMVAU - Invalidate Cache single entry
+                        * with MVA to PoU
+                        *      MCR p15, 0, r0, c7, c5, 1
+                        */
+                       for (uint32_t cacheline = 0;
+                               cacheline < size * count;
+                               cacheline += 64) {
+                               retval = dpm->instr_write_data_r0(dpm,
+                                               ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
+                                               address + cacheline);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                       }
+               }
+
+               /* invalidate D-Cache */
+               if (armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) {
+                       /* DCIMVAC - Invalidate data Cache line
+                        * with MVA to PoC
+                        *      MCR p15, 0, r0, c7, c6, 1
+                        */
+                       for (uint32_t cacheline = 0;
+                               cacheline < size * count;
+                               cacheline += 64) {
+                               retval = dpm->instr_write_data_r0(dpm,
+                                               ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
+                                               address + cacheline);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                       }
+               }
+
+               /* (void) */ dpm->finish(dpm);
+       }
+       return retval;
+}
 
 /*
  * Cortex-A Memory access
@@ -2209,61 +2275,6 @@ static int cortex_a_write_phys_memory(struct target 
*target,
                }
        }
 
-
-       /* REVISIT this op is generic ARMv7-A/R stuff */
-       if (retval == ERROR_OK && target->state == TARGET_HALTED) {
-               struct arm_dpm *dpm = armv7a->arm.dpm;
-
-               retval = dpm->prepare(dpm);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               /* The Cache handling will NOT work with MMU active, the
-                * wrong addresses will be invalidated!
-                *
-                * For both ICache and DCache, walk all cache lines in the
-                * address range. Cortex-A has fixed 64 byte line length.
-                *
-                * REVISIT per ARMv7, these may trigger watchpoints ...
-                */
-
-               /* invalidate I-Cache */
-               if (armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled) {
-                       /* ICIMVAU - Invalidate Cache single entry
-                        * with MVA to PoU
-                        *      MCR p15, 0, r0, c7, c5, 1
-                        */
-                       for (uint32_t cacheline = 0;
-                               cacheline < size * count;
-                               cacheline += 64) {
-                               retval = dpm->instr_write_data_r0(dpm,
-                                               ARMV4_5_MCR(15, 0, 0, 7, 5, 1),
-                                               address + cacheline);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                       }
-               }
-
-               /* invalidate D-Cache */
-               if (armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) {
-                       /* DCIMVAC - Invalidate data Cache line
-                        * with MVA to PoC
-                        *      MCR p15, 0, r0, c7, c6, 1
-                        */
-                       for (uint32_t cacheline = 0;
-                               cacheline < size * count;
-                               cacheline += 64) {
-                               retval = dpm->instr_write_data_r0(dpm,
-                                               ARMV4_5_MCR(15, 0, 0, 7, 6, 1),
-                                               address + cacheline);
-                               if (retval != ERROR_OK)
-                                       return retval;
-                       }
-               }
-
-               /* (void) */ dpm->finish(dpm);
-       }
-
        return retval;
 }
 
@@ -2271,7 +2282,7 @@ static int cortex_a_write_memory(struct target *target, 
uint32_t address,
        uint32_t size, uint32_t count, const uint8_t *buffer)
 {
        int mmu_enabled = 0;
-       uint32_t virt, phys;
+       uint32_t virt = 0, phys;
        int retval;
        struct armv7a_common *armv7a = target_to_armv7a(target);
        struct adiv5_dap *swjdp = armv7a->arm.dap;
@@ -2304,6 +2315,12 @@ static int cortex_a_write_memory(struct target *target, 
uint32_t address,
                }
                retval = cortex_a_write_phys_memory(target, address, size,
                                count, buffer);
+               if (retval == ERROR_OK) {
+                       if (mmu_enabled)
+                               retval = 
cortex_a_invalidate_instruction_data_cacheline(target, virt, size, count);
+                       else
+                               retval = 
cortex_a_invalidate_instruction_data_cacheline(target, address, size, count);
+               }
        } else {
                if (mmu_enabled) {
                        retval = cortex_a_check_address(target, address);

-- 

------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=164703151&iu=/4140/ostg.clktrk
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to