powerpc: Add POWER10 architected mode
authorAlistair Popple <alistair@popple.id.au>
Thu, 21 May 2020 01:43:41 +0000 (11:43 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 2 Jun 2020 10:59:20 +0000 (20:59 +1000)
PVR value of 0x0F000006 means we are arch v3.1 compliant (i.e.
POWER10). This is used by phyp and kvm when booting as a pseries guest
to detect the presence of new P10 features and to enable the
appropriate hwcap and facility bits.

Signed-off-by: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
[mpe: Fall through to __init_FSCR rather than duplicating it, drop
      hack to set current->thread.fscr now that is handled elsewhere.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200521014341.29095-8-alistair@popple.id.au
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/mmu.h
arch/powerpc/include/asm/prom.h
arch/powerpc/kernel/cpu_setup_power.S
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/prom_init.c

index 1559dbf72842ac4583301dc82ca345a16a9a3fc7..bac2252c839e22083cc0d474bfe6c8573dea539b 100644 (file)
@@ -468,6 +468,17 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1 | \
                               CPU_FTR_P9_TM_HV_ASSIST | \
                               CPU_FTR_P9_TM_XER_SO_BUG)
+#define CPU_FTRS_POWER10 (CPU_FTR_LWSYNC | \
+           CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
+           CPU_FTR_MMCRA | CPU_FTR_SMT | \
+           CPU_FTR_COHERENT_ICACHE | \
+           CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
+           CPU_FTR_DSCR | CPU_FTR_SAO  | \
+           CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
+           CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
+           CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
+           CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
+           CPU_FTR_ARCH_31)
 #define CPU_FTRS_CELL  (CPU_FTR_LWSYNC | \
            CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -486,14 +497,14 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTRS_POSSIBLE      \
            (CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 | \
             CPU_FTR_ALTIVEC_COMP | CPU_FTR_VSX_COMP | CPU_FTRS_POWER9 | \
-            CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2)
+            CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
 #else
 #define CPU_FTRS_POSSIBLE      \
            (CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
             CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
             CPU_FTRS_POWER8 | CPU_FTRS_CELL | CPU_FTRS_PA6T | \
             CPU_FTR_VSX_COMP | CPU_FTR_ALTIVEC_COMP | CPU_FTRS_POWER9 | \
-            CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2)
+            CPU_FTRS_POWER9_DD2_1 | CPU_FTRS_POWER9_DD2_2 | CPU_FTRS_POWER10)
 #endif /* CONFIG_CPU_LITTLE_ENDIAN */
 #endif
 #else
index cf2a08bfd5cdb849d19b8eab7570f28a93ae3f93..f4ac25d4df05a4af4c9fe1ffc1c5b74a17fa1b29 100644 (file)
 #define MMU_FTRS_POWER7                MMU_FTRS_POWER6
 #define MMU_FTRS_POWER8                MMU_FTRS_POWER6
 #define MMU_FTRS_POWER9                MMU_FTRS_POWER6
+#define MMU_FTRS_POWER10       MMU_FTRS_POWER6
 #define MMU_FTRS_CELL          MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
                                MMU_FTR_CI_LARGE_PAGE
 #define MMU_FTRS_PA6T          MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
index 94e3fd54f2c8e8f050a7cfd6fe3ce080cfe200d4..324a13351749ae185e840c50ba5de4e6d44bbd10 100644 (file)
@@ -117,6 +117,7 @@ extern int of_read_drc_info_cell(struct property **prop,
 #define OV1_PPC_2_07           0x01    /* set if we support PowerPC 2.07 */
 
 #define OV1_PPC_3_00           0x80    /* set if we support PowerPC 3.00 */
+#define OV1_PPC_3_1                    0x40    /* set if we support PowerPC 3.1 */
 
 /* Option vector 2: Open Firmware options supported */
 #define OV2_REAL_MODE          0x20    /* set if we want OF in real mode */
index f91ecb10d0ae758604578cc5d97990f9dcf14466..efdcfa714106da016037dc9db36eac7bb1f30099 100644 (file)
@@ -91,10 +91,15 @@ _GLOBAL(__restore_cpu_power8)
        mtlr    r11
        blr
 
+_GLOBAL(__setup_cpu_power10)
+       mflr    r11
+       bl      __init_FSCR_power10
+       b       1f
+
 _GLOBAL(__setup_cpu_power9)
        mflr    r11
        bl      __init_FSCR
-       bl      __init_PMU
+1:     bl      __init_PMU
        bl      __init_hvmode_206
        mtlr    r11
        beqlr
@@ -116,10 +121,15 @@ _GLOBAL(__setup_cpu_power9)
        mtlr    r11
        blr
 
+_GLOBAL(__restore_cpu_power10)
+       mflr    r11
+       bl      __init_FSCR_power10
+       b       1f
+
 _GLOBAL(__restore_cpu_power9)
        mflr    r11
        bl      __init_FSCR
-       bl      __init_PMU
+1:     bl      __init_PMU
        mfmsr   r3
        rldicl. r0,r3,4,63
        mtlr    r11
@@ -182,6 +192,12 @@ __init_LPCR_ISA300:
        isync
        blr
 
+__init_FSCR_power10:
+       mfspr   r3, SPRN_FSCR
+       ori     r3, r3, FSCR_PREFIX
+       mtspr   SPRN_FSCR, r3
+       // fall through
+
 __init_FSCR:
        mfspr   r3,SPRN_FSCR
        ori     r3,r3,FSCR_TAR|FSCR_EBB
index 8ed5537349191da09ad5b3ae9ce8729fb65b625f..b4066354f07300cea10be112e3dd3fd78758bc88 100644 (file)
@@ -70,6 +70,8 @@ extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec);
 extern void __restore_cpu_power8(void);
 extern void __setup_cpu_power9(unsigned long offset, struct cpu_spec* spec);
 extern void __restore_cpu_power9(void);
+extern void __setup_cpu_power10(unsigned long offset, struct cpu_spec* spec);
+extern void __restore_cpu_power10(void);
 extern long __machine_check_early_realmode_p7(struct pt_regs *regs);
 extern long __machine_check_early_realmode_p8(struct pt_regs *regs);
 extern long __machine_check_early_realmode_p9(struct pt_regs *regs);
@@ -119,6 +121,10 @@ extern void __restore_cpu_e6500(void);
                                 PPC_FEATURE2_ARCH_3_00 | \
                                 PPC_FEATURE2_HAS_IEEE128 | \
                                 PPC_FEATURE2_DARN )
+#define COMMON_USER_POWER10    COMMON_USER_POWER9
+#define COMMON_USER2_POWER10   (COMMON_USER2_POWER9 | \
+                                PPC_FEATURE2_ARCH_3_1 | \
+                                PPC_FEATURE2_MMA)
 
 #ifdef CONFIG_PPC_BOOK3E_64
 #define COMMON_USER_BOOKE      (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE)
@@ -367,6 +373,22 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .cpu_restore            = __restore_cpu_power9,
                .platform               = "power9",
        },
+       {       /* 3.1-compliant processor, i.e. Power10 "architected" mode */
+               .pvr_mask               = 0xffffffff,
+               .pvr_value              = 0x0f000006,
+               .cpu_name               = "POWER10 (architected)",
+               .cpu_features           = CPU_FTRS_POWER10,
+               .cpu_user_features      = COMMON_USER_POWER10,
+               .cpu_user_features2     = COMMON_USER2_POWER10,
+               .mmu_features           = MMU_FTRS_POWER10,
+               .icache_bsize           = 128,
+               .dcache_bsize           = 128,
+               .oprofile_type          = PPC_OPROFILE_INVALID,
+               .oprofile_cpu_type      = "ppc64/ibm-compat-v1",
+               .cpu_setup              = __setup_cpu_power10,
+               .cpu_restore            = __restore_cpu_power10,
+               .platform               = "power10",
+       },
        {       /* Power7 */
                .pvr_mask               = 0xffff0000,
                .pvr_value              = 0x003f0000,
index e3a9fde51c4f09a440f2a3bc65dea45da8101fd9..5f15b10eb007e7689b25639e6627c5f05ab10826 100644 (file)
@@ -920,7 +920,7 @@ struct option_vector6 {
 } __packed;
 
 struct ibm_arch_vec {
-       struct { u32 mask, val; } pvrs[12];
+       struct { u32 mask, val; } pvrs[14];
 
        u8 num_vectors;
 
@@ -973,6 +973,14 @@ static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = {
                        .mask = cpu_to_be32(0xffff0000), /* POWER9 */
                        .val  = cpu_to_be32(0x004e0000),
                },
+               {
+                       .mask = cpu_to_be32(0xffff0000), /* POWER10 */
+                       .val  = cpu_to_be32(0x00800000),
+               },
+               {
+                       .mask = cpu_to_be32(0xffffffff), /* all 3.1-compliant */
+                       .val  = cpu_to_be32(0x0f000006),
+               },
                {
                        .mask = cpu_to_be32(0xffffffff), /* all 3.00-compliant */
                        .val  = cpu_to_be32(0x0f000005),
@@ -1002,7 +1010,7 @@ static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = {
                .byte1 = 0,
                .arch_versions = OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
                                 OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07,
-               .arch_versions3 = OV1_PPC_3_00,
+               .arch_versions3 = OV1_PPC_3_00 | OV1_PPC_3_1,
        },
 
        .vec2_len = VECTOR_LENGTH(sizeof(struct option_vector2)),