This is an automated email from Gerrit.

Vladimir Svoboda ([email protected]) just uploaded a new patch set to Gerrit, 
which you can find at http://openocd.zylin.com/2337

-- gerrit

commit 4124bb1141064ea12c75488b582c9c6b9ff1ab2e
Author: Vladimir Svoboda <[email protected]>
Date:   Thu Oct 9 16:03:29 2014 +0200

    cortex-a/armv7a: Clean d-cache before reading
    
    Without this patch, when the data cache is enabled on Cortex-A9, GDB
    shows the data from memory where the expected data are actually in the
    cache.
    This patch cleans the cache lines of the addresses which must be read by
    the function cortex_a_read_memory().
    There is a new attribute in the structure "armv7a_cache_common" called
    "flush_vaddress_data_cache" which is a pointer to a function which
    should clean a cache line based on a virtual address.
    This function is called from cortex_a_read_memory() at each memory
    access (if d-cache is enabled).
    
    Change-Id: I14696b85539e64568b5213a60e909a5faf00850c
    Signed-off-by: Vladimir Svoboda <[email protected]>

diff --git a/jimtcl b/jimtcl
index 72bbd6c..2c1eba9 160000
--- a/jimtcl
+++ b/jimtcl
@@ -1 +1 @@
-Subproject commit 72bbd6c5a327bdc1d5ea8cb12502640860b1fc44
+Subproject commit 2c1eba991e21a6f0b531fb0f83e21f9e6ee7c515
diff --git a/src/target/armv7a.c b/src/target/armv7a.c
index bf474d3..fd6336b 100644
--- a/src/target/armv7a.c
+++ b/src/target/armv7a.c
@@ -398,6 +398,61 @@ static int  armv7a_flush_all_data(struct target *target)
        return retval;
 }
 
+static int _armv7a_flush_vaddress_data(struct target *target, uint32_t address)
+{
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       struct arm_dpm *dpm = armv7a->arm.dpm;
+       int retval;
+       /*  check that cache data is on at target halt */
+       if (!armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) {
+               LOG_INFO("flushed not performed :cache not on at target halt");
+               return ERROR_OK;
+       }
+       retval = dpm->prepare(dpm);
+
+       if (retval == ERROR_OK) {
+               /* Clean chache by virtual address */
+               retval = dpm->instr_write_data_r0(dpm, ARMV4_5_MCR(15, 0, 0, 7, 
10, 1),
+                               address);
+       }
+
+       if (retval != ERROR_OK) {
+               LOG_ERROR("flushed failed");
+               dpm->finish(dpm);
+       }
+
+       return retval;
+}
+
+static int  armv7a_flush_vaddress_data(struct target *target, uint32_t address)
+{
+       int retval = ERROR_FAIL;
+       /*  check that armv7a_cache is correctly identify */
+       struct armv7a_common *armv7a = target_to_armv7a(target);
+       if (armv7a->armv7a_mmu.armv7a_cache.ctype == -1) {
+               LOG_ERROR("trying to flush un-identified cache");
+               return retval;
+       }
+
+       if (target->smp) {
+               /*  look if all the other target have been flushed in order to 
flush level
+                *  2 */
+               struct target_list *head;
+               struct target *curr;
+               head = target->head;
+               while (head != (struct target_list *)NULL) {
+                       curr = head->target;
+                       if (curr->state == TARGET_HALTED) {
+                               LOG_INFO("Wait flushing data l1 on core %" 
PRId32, curr->coreid);
+                               retval = _armv7a_flush_vaddress_data(curr, 
address);
+                       }
+                       head = head->next;
+               }
+       } else
+               retval = _armv7a_flush_vaddress_data(target, address);
+       return retval;
+}
+
 /* L2 is not specific to armv7a  a specific file is needed */
 static int armv7a_l2x_flush_all_data(struct target *target)
 {
@@ -716,6 +771,8 @@ int armv7a_identify_cache(struct target *target)
                        armv7a_handle_inner_cache_info_command;
                armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache =
                        armv7a_flush_all_data;
+                       
armv7a->armv7a_mmu.armv7a_cache.flush_vaddress_data_cache =
+                       armv7a_flush_vaddress_data;
        }
        armv7a->armv7a_mmu.armv7a_cache.ctype = 0;
 
diff --git a/src/target/armv7a.h b/src/target/armv7a.h
index 341114b..3fd4195 100644
--- a/src/target/armv7a.h
+++ b/src/target/armv7a.h
@@ -71,6 +71,7 @@ struct armv7a_cache_common {
        /* l2 external unified cache if some */
        void *l2_cache;
        int (*flush_all_data_cache)(struct target *target);
+       int (*flush_vaddress_data_cache)(struct target *target, uint32_t 
address);
        int (*display_cache_info)(struct command_context *cmd_ctx,
                        struct armv7a_cache_common *armv7a_cache);
 };
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index 0393a44..6f0d84f 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -2112,8 +2112,8 @@ static int cortex_a_read_phys_memory(struct target 
*target,
 
        if (count && buffer) {
 
-               if (armv7a->memory_ap_available && (apsel == 
armv7a->memory_ap)) {
 
+               if (armv7a->memory_ap_available && (apsel == 
armv7a->memory_ap)) {
                        /* read memory through AHB-AP */
                        retval = mem_ap_sel_read_buf(swjdp, armv7a->memory_ap, 
buffer, size, count, address);
                } else {
@@ -2152,6 +2152,26 @@ static int cortex_a_read_memory(struct target *target, 
uint32_t address,
                        return retval;
        }
 
+       if (armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) {
+               if (armv7a->armv7a_mmu.armv7a_cache.flush_vaddress_data_cache) {
+                       /* Clean every line of cache that may contain the 
information we
+                        * need. We may have to clean up to 1 + 
(size*count/lineLength)
+                        * lines.
+                        */
+                       uint32_t lineLength = 
armv7a->armv7a_mmu.armv7a_cache.d_u_size.linelen;
+                       uint32_t maxAddress = (address + (size * count)) & 
~(lineLength-1);
+                       uint32_t currentAddress = address & ~(lineLength-1);
+
+                       do {
+                               LOG_DEBUG("Cleaning cache at virtual address 
v:0x%" PRIx32,
+                                       currentAddress);
+                               
armv7a->armv7a_mmu.armv7a_cache.flush_vaddress_data_cache(target, 
currentAddress);
+
+                               currentAddress += lineLength;
+                       } while (currentAddress <= maxAddress);
+               }
+       }
+
        if (armv7a->memory_ap_available && (apsel == armv7a->memory_ap)) {
                if (mmu_enabled) {
                        virt = address;

-- 

------------------------------------------------------------------------------
Meet PCI DSS 3.0 Compliance Requirements with EventLog Analyzer
Achieve PCI DSS 3.0 Compliant Status with Out-of-the-box PCI DSS Reports
Are you Audit-Ready for PCI DSS 3.0 Compliance? Download White paper
Comply to PCI DSS 3.0 Requirement 10 and 11.5 with EventLog Analyzer
http://pubads.g.doubleclick.net/gampad/clk?id=154622311&iu=/4140/ostg.clktrk
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to