[PATCH v2 7/7] powerpc: Add POWER10 architected mode
Jordan Niethe
jniethe5 at gmail.com
Tue May 19 13:58:32 AEST 2020
On Tue, May 19, 2020 at 10:48 AM Alistair Popple <alistair at popple.id.au> wrote:
>
> 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 at popple.id.au>
> Signed-off-by: Cédric Le Goater <clg at kaod.org>
> ---
> arch/powerpc/include/asm/cputable.h | 15 ++++++++++++--
> arch/powerpc/include/asm/mmu.h | 1 +
> arch/powerpc/include/asm/prom.h | 1 +
> arch/powerpc/kernel/cpu_setup_power.S | 20 ++++++++++++++++--
> arch/powerpc/kernel/cputable.c | 30 +++++++++++++++++++++++++++
> arch/powerpc/kernel/prom_init.c | 12 +++++++++--
> 6 files changed, 73 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
> index 36f894dea9e7..10b6d93c9d0b 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -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
> diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
> index 0699cfeeb8c9..17b19510f204 100644
> --- a/arch/powerpc/include/asm/mmu.h
> +++ b/arch/powerpc/include/asm/mmu.h
> @@ -122,6 +122,7 @@
> #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 | \
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index 94e3fd54f2c8..324a13351749 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -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 */
> diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
> index a460298c7ddb..f3730cf904fa 100644
> --- a/arch/powerpc/kernel/cpu_setup_power.S
> +++ b/arch/powerpc/kernel/cpu_setup_power.S
> @@ -91,10 +91,15 @@ _GLOBAL(__restore_cpu_power8)
> mtlr r11
> blr
>
> +_GLOBAL(__setup_cpu_power10)
> + mflr r11
> + bl __init_FSCR_P10
> + 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_P10
> + 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_P10:
> + mfspr r3,SPRN_FSCR
> + ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB|FSCR_PREFIX
> + mtspr SPRN_FSCR,r3
> + blr
> +
> __init_FSCR:
> mfspr r3,SPRN_FSCR
> ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB
> diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
> index 13eba2eb46fe..a17eeb311cdb 100644
> --- a/arch/powerpc/kernel/cputable.c
> +++ b/arch/powerpc/kernel/cputable.c
> @@ -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)
> @@ -127,6 +133,14 @@ extern void __restore_cpu_e6500(void);
> PPC_FEATURE_BOOKE)
> #endif
>
> +#ifdef CONFIG_PPC64
> +static void setup_cpu_power10(unsigned long offset, struct cpu_spec* spec)
> +{
> + __setup_cpu_power10(offset, spec);
> + current->thread.fscr |= FSCR_PREFIX;
> +}
> +#endif
> +
> static struct cpu_spec __initdata cpu_specs[] = {
> #ifdef CONFIG_PPC_BOOK3S_64
> { /* PPC970 */
> @@ -367,6 +381,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,
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 806be751c336..1ecadbd7e8b2 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -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),
Should there be a POWER10 (raw) entry added to cpu_specs[] for this?
> + },
> + {
> + .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)),
> --
> 2.20.1
>
More information about the Linuxppc-dev
mailing list