]> www.infradead.org Git - users/borneoa/openocd-next.git/commitdiff
target/armv8: update MPIDR decoding
authorDaniel Goehring <dgoehrin@os.amperecomputing.com>
Tue, 18 Jan 2022 17:34:25 +0000 (12:34 -0500)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 21 Jun 2025 07:35:31 +0000 (07:35 +0000)
Update MPIDR decode to support the multithreading (MT) bit.

If detected, socket, cluster, core and multithread affinity levels are
decoded and displayed.

Change-Id: I43569141fa0eef8ee8fc16c187a4af3c23e97db8
Signed-off-by: Daniel Goehring <dgoehrin@os.amperecomputing.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7190
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Tested-by: jenkins
src/target/armv8.c
src/target/armv8.h

index 40390731e84c178f4ea37e64277f3fef3378dddd..ece49c2a26d38417def418f6add50983b75ad3ba 100644 (file)
@@ -883,12 +883,27 @@ int armv8_read_mpidr(struct armv8_common *armv8)
        int retval = ERROR_FAIL;
        struct arm *arm = &armv8->arm;
        struct arm_dpm *dpm = armv8->arm.dpm;
-       uint32_t mpidr;
+       uint64_t mpidr;
+       uint8_t multi_processor_system;
+       uint8_t aff3;
+       uint8_t aff2;
+       uint8_t aff1;
+       uint8_t aff0;
+       uint8_t mt;
 
        retval = dpm->prepare(dpm);
        if (retval != ERROR_OK)
                goto done;
 
+       /*
+        * TODO: BUG - routine armv8_dpm_modeswitch() doesn't re-evaluate 'arm->dpm->core_state'.
+        * If the core is halted in EL0 AArch32 while EL1 is in AArch64, the modeswitch moves the core
+        * to EL1, but there is no re-evaluation of dpm->arm->core_state. As a result, while the core
+        * is in AArch64, the code considers the system still in AArch32. The read of MPIDR would
+        * select the instruction based on the old core_state. The call to 'armv8_dpm_get_core_state()'
+        * below could also potentially return the incorrect execution state for the current EL.
+        */
+
        /* check if we're in an unprivileged mode */
        if (armv8_curel_from_core_mode(arm->core_mode) < SYSTEM_CUREL_EL1) {
                retval = armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);
@@ -896,17 +911,39 @@ int armv8_read_mpidr(struct armv8_common *armv8)
                        return retval;
        }
 
-       retval = dpm->instr_read_data_r0(dpm, armv8_opcode(armv8, READ_REG_MPIDR), &mpidr);
+       retval = dpm->instr_read_data_r0_64(dpm, armv8_opcode(armv8, READ_REG_MPIDR), &mpidr);
        if (retval != ERROR_OK)
                goto done;
        if (mpidr & 1U<<31) {
-               armv8->multi_processor_system = (mpidr >> 30) & 1;
-               armv8->cluster_id = (mpidr >> 8) & 0xf;
-               armv8->cpu_id = mpidr & 0x3;
-               LOG_INFO("%s cluster %x core %x %s", target_name(armv8->arm.target),
-                       armv8->cluster_id,
-                       armv8->cpu_id,
-                       armv8->multi_processor_system == 0 ? "multi core" : "single core");
+               multi_processor_system = (mpidr >> 30) & 1;
+               aff3 = (mpidr >> 32) & 0xff;
+               aff2 = (mpidr >> 16) & 0xff;
+               aff1 = (mpidr >> 8) & 0xff;
+               aff0 = mpidr & 0xff;
+               mt = (mpidr >> 24) & 0x1;
+               if (armv8_dpm_get_core_state(&armv8->dpm) == ARM_STATE_AARCH64) {
+                       if (mt)
+                               LOG_INFO("%s socket %" PRIu32 " cluster %" PRIu32 " core %" PRIu32 " thread %" PRIu32 " %s",
+                                       target_name(armv8->arm.target),
+                                       aff3, aff2, aff1, aff0,
+                                       multi_processor_system == 0 ? "multi core" : "single core");
+                       else
+                               LOG_INFO("%s socket %" PRIu32 " cluster %" PRIu32 " core %" PRIu32 " %s",
+                                       target_name(armv8->arm.target),
+                                       aff3, aff1, aff0,
+                                       multi_processor_system == 0 ? "multi core" : "single core");
+               } else {
+                       if (mt)
+                               LOG_INFO("%s cluster %" PRIu32 " core %" PRIu32 " thread %" PRIu32 " %s",
+                                       target_name(armv8->arm.target),
+                                       aff2, aff1, aff0,
+                                       multi_processor_system == 0 ? "multi core" : "single core");
+                       else
+                               LOG_INFO("%s cluster %" PRIu32 " core %" PRIu32 " %s",
+                                       target_name(armv8->arm.target),
+                                       aff1, aff0,
+                                       multi_processor_system == 0 ? "multi core" : "single core");
+               }
        } else
                LOG_ERROR("mpidr not in multiprocessor format");
 
index dba12f9666f26033ffa3124fad8a54a28242c365..64ca5ec9d4b120257b2b3c8e5b32612fce69d87d 100644 (file)
@@ -195,11 +195,6 @@ struct armv8_common {
 
        const uint32_t *opcodes;
 
-       /* mdir */
-       uint8_t multi_processor_system;
-       uint8_t cluster_id;
-       uint8_t cpu_id;
-
        /* armv8 aarch64 need below information for page translation */
        uint8_t va_size;
        uint8_t pa_size;