arm64/cpufeature: Introduce ID_DFR1 CPU register
authorAnshuman Khandual <anshuman.khandual@arm.com>
Tue, 19 May 2020 09:40:42 +0000 (15:10 +0530)
committerWill Deacon <will@kernel.org>
Thu, 21 May 2020 14:47:11 +0000 (15:47 +0100)
This adds basic building blocks required for ID_DFR1 CPU register which
provides top level information about the debug system in AArch32 state.
We hide the register from KVM guests, as we don't emulate the 'MTPMU'
feature.

This is added per ARM DDI 0487F.a specification.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: kvmarm@lists.cs.columbia.edu
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-kernel@vger.kernel.org
Suggested-by: Will Deacon <will@kernel.org>
Reviewed-by : Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
Link: https://lore.kernel.org/r/1589881254-10082-6-git-send-email-anshuman.khandual@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/cpu.h
arch/arm64/include/asm/sysreg.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/cpuinfo.c
arch/arm64/kvm/sys_regs.c

index 464e828..d9a78bd 100644 (file)
@@ -33,6 +33,7 @@ struct cpuinfo_arm64 {
        u64             reg_id_aa64zfr0;
 
        u32             reg_id_dfr0;
+       u32             reg_id_dfr1;
        u32             reg_id_isar0;
        u32             reg_id_isar1;
        u32             reg_id_isar2;
index d0ea916..c1c97e0 100644 (file)
 #define SYS_ID_PFR1_EL1                        sys_reg(3, 0, 0, 1, 1)
 #define SYS_ID_PFR2_EL1                        sys_reg(3, 0, 0, 3, 4)
 #define SYS_ID_DFR0_EL1                        sys_reg(3, 0, 0, 1, 2)
+#define SYS_ID_DFR1_EL1                        sys_reg(3, 0, 0, 3, 5)
 #define SYS_ID_AFR0_EL1                        sys_reg(3, 0, 0, 1, 3)
 #define SYS_ID_MMFR0_EL1               sys_reg(3, 0, 0, 1, 4)
 #define SYS_ID_MMFR1_EL1               sys_reg(3, 0, 0, 1, 5)
 #define ID_ISAR4_WITHSHIFTS_SHIFT      4
 #define ID_ISAR4_UNPRIV_SHIFT          0
 
+#define ID_DFR1_MTPMU_SHIFT            0
+
 #define ID_ISAR0_DIVIDE_SHIFT          24
 #define ID_ISAR0_DEBUG_SHIFT           20
 #define ID_ISAR0_COPROC_SHIFT          16
index b81b74d..7a7ddbd 100644 (file)
@@ -457,6 +457,11 @@ static const struct arm64_ftr_bits ftr_id_dfr0[] = {
        ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_id_dfr1[] = {
+       S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR1_MTPMU_SHIFT, 4, 0),
+       ARM64_FTR_END,
+};
+
 static const struct arm64_ftr_bits ftr_zcr[] = {
        ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE,
                ZCR_ELx_LEN_SHIFT, ZCR_ELx_LEN_SIZE, 0),        /* LEN */
@@ -527,6 +532,7 @@ static const struct __ftr_reg_entry {
        ARM64_FTR_REG(SYS_MVFR1_EL1, ftr_generic_32bits),
        ARM64_FTR_REG(SYS_MVFR2_EL1, ftr_mvfr2),
        ARM64_FTR_REG(SYS_ID_PFR2_EL1, ftr_id_pfr2),
+       ARM64_FTR_REG(SYS_ID_DFR1_EL1, ftr_id_dfr1),
 
        /* Op1 = 0, CRn = 0, CRm = 4 */
        ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0),
@@ -720,6 +726,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 
        if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
                init_cpu_ftr_reg(SYS_ID_DFR0_EL1, info->reg_id_dfr0);
+               init_cpu_ftr_reg(SYS_ID_DFR1_EL1, info->reg_id_dfr1);
                init_cpu_ftr_reg(SYS_ID_ISAR0_EL1, info->reg_id_isar0);
                init_cpu_ftr_reg(SYS_ID_ISAR1_EL1, info->reg_id_isar1);
                init_cpu_ftr_reg(SYS_ID_ISAR2_EL1, info->reg_id_isar2);
@@ -835,6 +842,8 @@ static int update_32bit_cpu_features(int cpu, struct cpuinfo_arm64 *info,
 
        taint |= check_update_ftr_reg(SYS_ID_DFR0_EL1, cpu,
                                      info->reg_id_dfr0, boot->reg_id_dfr0);
+       taint |= check_update_ftr_reg(SYS_ID_DFR1_EL1, cpu,
+                                     info->reg_id_dfr1, boot->reg_id_dfr1);
        taint |= check_update_ftr_reg(SYS_ID_ISAR0_EL1, cpu,
                                      info->reg_id_isar0, boot->reg_id_isar0);
        taint |= check_update_ftr_reg(SYS_ID_ISAR1_EL1, cpu,
@@ -998,6 +1007,7 @@ static u64 __read_sysreg_by_encoding(u32 sys_id)
        read_sysreg_case(SYS_ID_PFR1_EL1);
        read_sysreg_case(SYS_ID_PFR2_EL1);
        read_sysreg_case(SYS_ID_DFR0_EL1);
+       read_sysreg_case(SYS_ID_DFR1_EL1);
        read_sysreg_case(SYS_ID_MMFR0_EL1);
        read_sysreg_case(SYS_ID_MMFR1_EL1);
        read_sysreg_case(SYS_ID_MMFR2_EL1);
index cb79b08..50a2817 100644 (file)
@@ -362,6 +362,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
        /* Update the 32bit ID registers only if AArch32 is implemented */
        if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
                info->reg_id_dfr0 = read_cpuid(ID_DFR0_EL1);
+               info->reg_id_dfr1 = read_cpuid(ID_DFR1_EL1);
                info->reg_id_isar0 = read_cpuid(ID_ISAR0_EL1);
                info->reg_id_isar1 = read_cpuid(ID_ISAR1_EL1);
                info->reg_id_isar2 = read_cpuid(ID_ISAR2_EL1);
index b784b15..0723cfb 100644 (file)
@@ -1457,7 +1457,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
        ID_SANITISED(MVFR2_EL1),
        ID_UNALLOCATED(3,3),
        ID_SANITISED(ID_PFR2_EL1),
-       ID_UNALLOCATED(3,5),
+       ID_HIDDEN(ID_DFR1_EL1),
        ID_UNALLOCATED(3,6),
        ID_UNALLOCATED(3,7),