This is an automated email from Gerrit.

"Adrien Charruel <acharr...@nanoxplore.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8655

-- gerrit

commit d13faec9c595e7c99ac4bae22c998a1c583d5163
Author: Adrien Grassein <agrass...@nanoxplore.com>
Date:   Thu Jan 18 11:58:38 2024 +0100

    target/armv8: Handle instruction cache flush
    
    Some armv8 target have separate i-cache and d-cache.
    The actual code only handles the flush of the d-cache.
    
    Change-Id: I61a223b43c71646bbbed8fa63825360c67700988
    Signed-off-by: Adrien Grassein <agrass...@nanoxplore.com>
    Signed-off-by: Adrien Charruel <acharr...@nanoxplore.com>

diff --git a/src/target/armv8.h b/src/target/armv8.h
index 49ab3e5cb7..215e4333fc 100644
--- a/src/target/armv8.h
+++ b/src/target/armv8.h
@@ -162,6 +162,7 @@ struct armv8_cache_common {
        /* l2 external unified cache if some */
        void *l2_cache;
        int (*flush_all_data_cache)(struct target *target);
+       int (*flush_all_instruction_cache)(struct target *target);
        int (*display_cache_info)(struct command_invocation *cmd,
                        struct armv8_cache_common *armv8_cache);
 };
diff --git a/src/target/armv8_cache.c b/src/target/armv8_cache.c
index 66d4e00801..7d5645134f 100644
--- a/src/target/armv8_cache.c
+++ b/src/target/armv8_cache.c
@@ -140,6 +140,36 @@ done:
        return retval;
 }
 
+static int armv8_cache_i_inner_clean_inval_all(struct armv8_common *armv8)
+{
+       struct arm_dpm *dpm = armv8->arm.dpm;
+       int retval;
+
+       retval = armv8_i_cache_sanity_check(armv8);
+       if (retval != ERROR_OK)
+               return retval;
+
+       LOG_DEBUG("flushing cache");
+
+       retval = dpm->prepare(dpm);
+       if (retval != ERROR_OK)
+               goto done;
+
+       retval = dpm->instr_execute(dpm, armv8_opcode(armv8, 
ARMV8_OPC_ICIALLU));
+       if (retval != ERROR_OK)
+               goto done;
+
+       dpm->finish(dpm);
+       LOG_DEBUG("flushing cache done");
+       return retval;
+
+done:
+       LOG_ERROR("i-cache invalidate failed");
+       dpm->finish(dpm);
+
+       return retval;
+}
+
 int armv8_cache_i_inner_inval_virt(struct armv8_common *armv8, target_addr_t 
va, size_t size)
 {
        struct arm_dpm *dpm = armv8->arm.dpm;
@@ -252,6 +282,38 @@ static int  armv8_flush_all_data(struct target *target)
        return retval;
 }
 
+static int _armv8_flush_all_instruction(struct target *target)
+{
+       return armv8_cache_i_inner_clean_inval_all(target_to_armv8(target));
+}
+
+static int  armv8_flush_all_instruction(struct target *target)
+{
+       int retval = ERROR_FAIL;
+       /*  check that armv8_cache is correctly identify */
+       struct armv8_common *armv8 = target_to_armv8(target);
+       if (armv8->armv8_mmu.armv8_cache.info == -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;
+               foreach_smp_target(head, target->smp_targets) {
+                       struct target *curr = head->target;
+                       if (curr->state == TARGET_HALTED) {
+                               LOG_TARGET_INFO(curr, "Wait flushing 
instruction l1.");
+                               retval = _armv8_flush_all_instruction(curr);
+                       }
+               }
+       } else {
+               retval = _armv8_flush_all_instruction(target);
+       }
+       return retval;
+}
+
 static int get_cache_info(struct arm_dpm *dpm, int cl, int ct, uint32_t 
*cache_reg)
 {
        struct armv8_common *armv8 = dpm->arm->arch_info;
@@ -411,6 +473,12 @@ int armv8_identify_cache(struct armv8_common *armv8)
                armv8->armv8_mmu.armv8_cache.flush_all_data_cache =
                        armv8_flush_all_data;
        }
+       if (!armv8->armv8_mmu.armv8_cache.flush_all_instruction_cache) {
+               armv8->armv8_mmu.armv8_cache.display_cache_info =
+                       armv8_handle_inner_cache_info_command;
+               armv8->armv8_mmu.armv8_cache.flush_all_instruction_cache =
+                       armv8_flush_all_instruction;
+       }
 
 done:
        armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);
diff --git a/src/target/armv8_opcodes.c b/src/target/armv8_opcodes.c
index 2635b3ec5f..1a320bf57e 100644
--- a/src/target/armv8_opcodes.c
+++ b/src/target/armv8_opcodes.c
@@ -41,6 +41,7 @@ static const uint32_t a64_opcodes[ARMV8_OPC_NUM] = {
                [ARMV8_OPC_STRH_IP]     = ARMV8_STRH_IP(1, 0),
                [ARMV8_OPC_STRW_IP]     = ARMV8_STRW_IP(1, 0),
                [ARMV8_OPC_STRD_IP]     = ARMV8_STRD_IP(1, 0),
+               [ARMV8_OPC_ICIALLU]     = SYSTEM_ICIALLU,
 };
 
 static const uint32_t t32_opcodes[ARMV8_OPC_NUM] = {
@@ -68,6 +69,7 @@ static const uint32_t t32_opcodes[ARMV8_OPC_NUM] = {
                [ARMV8_OPC_STRB_IP]     = ARMV8_STRB_IP_T3(1, 0),
                [ARMV8_OPC_STRH_IP]     = ARMV8_STRH_IP_T3(1, 0),
                [ARMV8_OPC_STRW_IP]     = ARMV8_STRW_IP_T3(1, 0),
+               [ARMV8_OPC_ICIALLU]     = ARMV4_5_MCR(15, 0, 0, 7, 5, 0),
 };
 
 void armv8_select_opcodes(struct armv8_common *armv8, bool state_is_aarch64)
diff --git a/src/target/armv8_opcodes.h b/src/target/armv8_opcodes.h
index 9200dac723..4541bbd08a 100644
--- a/src/target/armv8_opcodes.h
+++ b/src/target/armv8_opcodes.h
@@ -72,6 +72,8 @@
 #define SYSTEM_DCCISW                  0x43F2
 #define SYSTEM_DCCSW                   0x43D2
 #define SYSTEM_ICIVAU                  0x5BA9
+/* SYSTEM_ICIALLU can't be encoded as other cache operation */
+#define SYSTEM_ICIALLU          0xd508751f
 #define SYSTEM_DCCVAU                  0x5BD9
 #define SYSTEM_DCCIVAC                 0x5BF1
 
@@ -207,6 +209,7 @@ enum armv8_opcode {
        ARMV8_OPC_LDRH_IP,
        ARMV8_OPC_LDRW_IP,
        ARMV8_OPC_LDRD_IP,
+       ARMV8_OPC_ICIALLU,
        ARMV8_OPC_NUM,
 };
 

-- 

Reply via email to