From: Daniel Goehring Date: Tue, 18 Jan 2022 17:34:25 +0000 (-0500) Subject: target/armv8: update MPIDR decoding X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=33ebae9abde0b67ad33bb527cf5a2c2f761ab2c4;p=users%2Fborneoa%2Fopenocd-next.git target/armv8: update MPIDR decoding 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 Reviewed-on: https://review.openocd.org/c/openocd/+/7190 Reviewed-by: Antonio Borneo Tested-by: jenkins --- diff --git a/src/target/armv8.c b/src/target/armv8.c index 40390731e..ece49c2a2 100644 --- a/src/target/armv8.c +++ b/src/target/armv8.c @@ -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"); diff --git a/src/target/armv8.h b/src/target/armv8.h index dba12f966..64ca5ec9d 100644 --- a/src/target/armv8.h +++ b/src/target/armv8.h @@ -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;