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 464e828a994ddc6e53da54e74e6cf8b6af3c79dc..d9a78bdec409fc59d577e4d313293826d9d650aa 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 d0ea916b85283ac114de6504732712a6b356850e..c1c97e08a799454fc804bd6a1066e367dab4c231 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 b81b74d6dc20260ba23a7450358bab1a66b21501..7a7ddbdc9c55f6b2c5803543aa64595121b5df08 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 cb79b083f97fb30ff1a106b9f89b2ae41477f89f..50a281703d9d7829746383c6488a45ecbf660f77 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 b784b156edb380cf71bb2a9976f17687a9e1e4be..0723cfbff7e99b6707d248b1a1180855c0f23e23 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),