mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-28 04:03:23 -04:00
powerpc: Add Power12 raw mode
Add CPU table entries for raw mode. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com> Tested-by: Praveen K Pandey <praveen@linux.ibm.com> Reviewed-by: Nikhil Kumar Singh <nikhilks@linux.ibm.com> Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/20260806051120.3703698-3-mahesh@linux.ibm.com
This commit is contained in:
committed by
Madhavan Srinivasan
parent
972a7b7872
commit
e671e147ea
@@ -9,10 +9,12 @@ void __setup_cpu_power7(unsigned long offset, struct cpu_spec *spec);
|
||||
void __setup_cpu_power8(unsigned long offset, struct cpu_spec *spec);
|
||||
void __setup_cpu_power9(unsigned long offset, struct cpu_spec *spec);
|
||||
void __setup_cpu_power10(unsigned long offset, struct cpu_spec *spec);
|
||||
void __setup_cpu_power12(unsigned long offset, struct cpu_spec *spec);
|
||||
void __restore_cpu_power7(void);
|
||||
void __restore_cpu_power8(void);
|
||||
void __restore_cpu_power9(void);
|
||||
void __restore_cpu_power10(void);
|
||||
void __restore_cpu_power12(void);
|
||||
|
||||
void __setup_cpu_e500v1(unsigned long offset, struct cpu_spec *spec);
|
||||
void __setup_cpu_e500v2(unsigned long offset, struct cpu_spec *spec);
|
||||
|
||||
@@ -194,6 +194,7 @@ static inline void cpu_feature_keys_init(void) { }
|
||||
#define CPU_FTR_DAWR1 LONG_ASM_CONST(0x0008000000000000)
|
||||
#define CPU_FTR_DEXCR_NPHIE LONG_ASM_CONST(0x0010000000000000)
|
||||
#define CPU_FTR_P11_PVR LONG_ASM_CONST(0x0020000000000000)
|
||||
#define CPU_FTR_ARCH_32 LONG_ASM_CONST(0x0040000000000000)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
@@ -457,6 +458,18 @@ static inline void cpu_feature_keys_init(void) { }
|
||||
|
||||
#define CPU_FTRS_POWER11 (CPU_FTRS_POWER10 | CPU_FTR_P11_PVR)
|
||||
|
||||
#define CPU_FTRS_POWER12 (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_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_ARCH_300 | CPU_FTR_ARCH_31 | CPU_FTR_ARCH_32 | \
|
||||
CPU_FTR_DAWR | CPU_FTR_DAWR1)
|
||||
|
||||
#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 | \
|
||||
@@ -476,7 +489,7 @@ static inline void cpu_feature_keys_init(void) { }
|
||||
(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_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11)
|
||||
CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11 | CPU_FTRS_POWER12)
|
||||
#else
|
||||
#define CPU_FTRS_POSSIBLE \
|
||||
(CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
|
||||
@@ -484,7 +497,7 @@ static inline void cpu_feature_keys_init(void) { }
|
||||
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_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11)
|
||||
CPU_FTRS_POWER9_DD2_3 | CPU_FTRS_POWER10 | CPU_FTRS_POWER11 | CPU_FTRS_POWER12)
|
||||
#endif /* CONFIG_CPU_LITTLE_ENDIAN */
|
||||
#endif
|
||||
#else
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
#define MMU_FTRS_POWER9 MMU_FTRS_POWER6
|
||||
#define MMU_FTRS_POWER10 MMU_FTRS_POWER6
|
||||
#define MMU_FTRS_POWER11 MMU_FTRS_POWER6
|
||||
#define MMU_FTRS_POWER12 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 | \
|
||||
|
||||
@@ -492,11 +492,12 @@
|
||||
* determine both the compatibility level which we want to emulate and the
|
||||
* compatibility level which the host is capable of emulating.
|
||||
*/
|
||||
#define PCR_ARCH_31 0x20 /* Architecture 3.1 */
|
||||
#define PCR_ARCH_300 0x10 /* Architecture 3.00 */
|
||||
#define PCR_ARCH_207 0x8 /* Architecture 2.07 */
|
||||
#define PCR_ARCH_206 0x4 /* Architecture 2.06 */
|
||||
#define PCR_ARCH_205 0x2 /* Architecture 2.05 */
|
||||
#define PCR_LOW_BITS (PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205 | PCR_ARCH_300)
|
||||
#define PCR_LOW_BITS (PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205 | PCR_ARCH_300 | PCR_ARCH_31)
|
||||
#define PCR_MASK ~(PCR_HIGH_BITS | PCR_LOW_BITS) /* PCR Reserved Bits */
|
||||
#define SPRN_HEIR 0x153 /* Hypervisor Emulated Instruction Register */
|
||||
#define SPRN_TLBINDEXR 0x154 /* P7 TLB control register */
|
||||
@@ -1344,6 +1345,7 @@
|
||||
#define PVR_POWER9 0x004E
|
||||
#define PVR_POWER10 0x0080
|
||||
#define PVR_POWER11 0x0082
|
||||
#define PVR_POWER12 0x0083
|
||||
#define PVR_BE 0x0070
|
||||
#define PVR_PA6T 0x0090
|
||||
|
||||
@@ -1356,6 +1358,7 @@
|
||||
#define PVR_ARCH_300 0x0f000005
|
||||
#define PVR_ARCH_31 0x0f000006
|
||||
#define PVR_ARCH_31_P11 0x0f000007
|
||||
#define PVR_ARCH_32 0x0f000008
|
||||
|
||||
/*
|
||||
* Kernel-internal sentinel for invalid processor compatibility modes.
|
||||
|
||||
@@ -37,8 +37,12 @@ static inline void ppc_after_tlbiel_barrier(void)
|
||||
* accelerators mapped will use tlbie (which does invalidate the copy)
|
||||
* to invalidate translations. It's not possible to limit POWER10 this
|
||||
* way due to local copy-paste.
|
||||
*
|
||||
* POWER12 does not need it.
|
||||
*/
|
||||
asm volatile(ASM_FTR_IFSET(PPC_CP_ABORT, "", %0) : : "i" (CPU_FTR_ARCH_31) : "memory");
|
||||
asm volatile(ASM_FTR_IF(PPC_CP_ABORT, "", %0, %1) :
|
||||
: "i" (CPU_FTR_ARCH_31|CPU_FTR_ARCH_32), "i" (CPU_FTR_ARCH_31)
|
||||
: "memory");
|
||||
}
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 /* TM w/out suspended state */
|
||||
#define PPC_FEATURE2_ARCH_3_1 0x00040000 /* ISA 3.1 */
|
||||
#define PPC_FEATURE2_MMA 0x00020000 /* Matrix Multiply Assist */
|
||||
#define PPC_FEATURE2_ARCH_3_2 0x00010000 /* ISA 3.2 */
|
||||
|
||||
/*
|
||||
* IMPORTANT!
|
||||
|
||||
@@ -286,3 +286,46 @@ void __restore_cpu_power10(void)
|
||||
init_HFSCR();
|
||||
init_PMU_HV();
|
||||
}
|
||||
|
||||
void __setup_cpu_power12(unsigned long offset, struct cpu_spec *t)
|
||||
{
|
||||
init_FSCR_power10();
|
||||
init_PMU();
|
||||
init_PMU_ISA31();
|
||||
|
||||
if (!init_hvmode_206(t))
|
||||
return;
|
||||
|
||||
mtspr(SPRN_PSSCR, 0);
|
||||
mtspr(SPRN_LPID, 0);
|
||||
mtspr(SPRN_PID, 0);
|
||||
mtspr(SPRN_AMOR, ~0);
|
||||
mtspr(SPRN_PCR, PCR_MASK);
|
||||
init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
|
||||
LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
|
||||
init_HFSCR();
|
||||
init_PMU_HV();
|
||||
}
|
||||
|
||||
void __restore_cpu_power12(void)
|
||||
{
|
||||
u64 msr;
|
||||
|
||||
init_FSCR_power10();
|
||||
init_PMU();
|
||||
init_PMU_ISA31();
|
||||
|
||||
msr = mfmsr();
|
||||
if (!(msr & MSR_HV))
|
||||
return;
|
||||
|
||||
mtspr(SPRN_PSSCR, 0);
|
||||
mtspr(SPRN_LPID, 0);
|
||||
mtspr(SPRN_PID, 0);
|
||||
mtspr(SPRN_AMOR, ~0);
|
||||
mtspr(SPRN_PCR, PCR_MASK);
|
||||
init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\
|
||||
LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0);
|
||||
init_HFSCR();
|
||||
init_PMU_HV();
|
||||
}
|
||||
|
||||
@@ -63,6 +63,11 @@
|
||||
#define COMMON_USER_POWER11 COMMON_USER_POWER10
|
||||
#define COMMON_USER2_POWER11 COMMON_USER2_POWER10
|
||||
|
||||
#define COMMON_USER_POWER12 COMMON_USER_POWER10
|
||||
#define COMMON_USER2_POWER12 (COMMON_USER2_POWER10 | \
|
||||
PPC_FEATURE2_ARCH_3_2)
|
||||
|
||||
|
||||
static struct cpu_spec cpu_specs[] __initdata = {
|
||||
{ /* PPC970 */
|
||||
.pvr_mask = 0xffff0000,
|
||||
@@ -485,6 +490,23 @@ static struct cpu_spec cpu_specs[] __initdata = {
|
||||
.machine_check_early = __machine_check_early_realmode_p10,
|
||||
.platform = "power11",
|
||||
},
|
||||
{ /* Power12 */
|
||||
.pvr_mask = 0xffff0000,
|
||||
.pvr_value = 0x00830000,
|
||||
.cpu_name = "Power12 (raw)",
|
||||
.cpu_features = CPU_FTRS_POWER12,
|
||||
.cpu_user_features = COMMON_USER_POWER12,
|
||||
.cpu_user_features2 = COMMON_USER2_POWER12,
|
||||
.mmu_features = MMU_FTRS_POWER12,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 6,
|
||||
.pmc_type = PPC_PMC_IBM,
|
||||
.cpu_setup = __setup_cpu_power12,
|
||||
.cpu_restore = __restore_cpu_power12,
|
||||
.machine_check_early = __machine_check_early_realmode_p10,
|
||||
.platform = "power12",
|
||||
},
|
||||
{ /* Cell Broadband Engine */
|
||||
.pvr_mask = 0xffff0000,
|
||||
.pvr_value = 0x00700000,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
/* Device-tree visible constants follow */
|
||||
#define ISA_V3_0B 3000
|
||||
#define ISA_V3_1 3100
|
||||
#define ISA_V3_2 3200
|
||||
|
||||
#define USABLE_PR (1U << 0)
|
||||
#define USABLE_OS (1U << 1)
|
||||
@@ -464,6 +465,35 @@ static int __init feat_enable_mce_power11(struct dt_cpu_feature *f)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void init_pmu_power12(void)
|
||||
{
|
||||
init_pmu_power10();
|
||||
}
|
||||
|
||||
static int __init feat_enable_pmu_power12(struct dt_cpu_feature *f)
|
||||
{
|
||||
hfscr_pmu_enable();
|
||||
|
||||
init_pmu_power12();
|
||||
init_pmu_registers = init_pmu_power12;
|
||||
|
||||
cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA;
|
||||
cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT;
|
||||
|
||||
cur_cpu_spec->num_pmcs = 6;
|
||||
cur_cpu_spec->pmc_type = PPC_PMC_IBM;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __init feat_enable_mce_power12(struct dt_cpu_feature *f)
|
||||
{
|
||||
cur_cpu_spec->platform = "power12";
|
||||
cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p10;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __init feat_enable_tm(struct dt_cpu_feature *f)
|
||||
{
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
@@ -655,9 +685,11 @@ static struct dt_cpu_feature_match __initdata
|
||||
{"machine-check-power9", feat_enable_mce_power9, 0},
|
||||
{"machine-check-power10", feat_enable_mce_power10, 0},
|
||||
{"machine-check-power11", feat_enable_mce_power11, 0},
|
||||
{"machine-check-power12", feat_enable_mce_power12, 0},
|
||||
{"performance-monitor-power9", feat_enable_pmu_power9, 0},
|
||||
{"performance-monitor-power10", feat_enable_pmu_power10, 0},
|
||||
{"performance-monitor-power11", feat_enable_pmu_power10, 0},
|
||||
{"performance-monitor-power12", feat_enable_pmu_power12, 0},
|
||||
{"event-based-branch-v3", feat_enable, 0},
|
||||
{"random-number-generator", feat_enable, 0},
|
||||
{"system-call-vectored", feat_disable, 0},
|
||||
@@ -712,6 +744,11 @@ static void __init cpufeatures_setup_start(u32 isa)
|
||||
if (PVR_VER(mfspr(SPRN_PVR)) >= PVR_POWER11)
|
||||
cur_cpu_spec->cpu_features |= CPU_FTR_P11_PVR;
|
||||
}
|
||||
|
||||
if (isa >= ISA_V3_2) {
|
||||
cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_32;
|
||||
cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_2;
|
||||
}
|
||||
}
|
||||
|
||||
static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)
|
||||
|
||||
@@ -304,6 +304,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
break;
|
||||
case 0x004e: /* POWER9 bits 12-15 give chip type */
|
||||
case 0x0080: /* POWER10 bit 12 gives SMT8/4 */
|
||||
case 0x0083: /* POWER12 bit 12 gives SMT8/4 */
|
||||
maj = (pvr >> 8) & 0x0F;
|
||||
min = pvr & 0xFF;
|
||||
break;
|
||||
|
||||
@@ -388,7 +388,7 @@ static void kvmppc_set_pvr_hv(struct kvm_vcpu *vcpu, u32 pvr)
|
||||
}
|
||||
|
||||
/* Dummy value used in computing PCR value below */
|
||||
#define PCR_ARCH_31 (PCR_ARCH_300 << 1)
|
||||
#define PCR_ARCH_32 (PCR_ARCH_31 << 1)
|
||||
|
||||
static inline unsigned long map_pcr_to_cap(unsigned long pcr)
|
||||
{
|
||||
@@ -417,7 +417,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
|
||||
struct kvmppc_vcore *vc = vcpu->arch.vcore;
|
||||
|
||||
/* We can (emulate) our own architecture version and anything older */
|
||||
if (cpu_has_feature(CPU_FTR_P11_PVR) || cpu_has_feature(CPU_FTR_ARCH_31))
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_32))
|
||||
host_pcr_bit = PCR_ARCH_32;
|
||||
else if (cpu_has_feature(CPU_FTR_P11_PVR) || cpu_has_feature(CPU_FTR_ARCH_31))
|
||||
host_pcr_bit = PCR_ARCH_31;
|
||||
else if (cpu_has_feature(CPU_FTR_ARCH_300))
|
||||
host_pcr_bit = PCR_ARCH_300;
|
||||
@@ -461,6 +463,9 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu *vcpu, u32 arch_compat)
|
||||
}
|
||||
guest_pcr_bit = PCR_ARCH_31;
|
||||
break;
|
||||
case PVR_ARCH_32:
|
||||
guest_pcr_bit = PCR_ARCH_32;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -184,9 +184,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize)
|
||||
va |= ssize << 8;
|
||||
sllp = get_sllp_encoding(apsize);
|
||||
va |= sllp << 5;
|
||||
asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 0), %1)
|
||||
: : "r" (va), "i" (CPU_FTR_ARCH_206)
|
||||
: "memory");
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_32)) {
|
||||
asm volatile(PPC_TLBIEL(%0, %1, 0, 0, 0) : : "r"(va), "r"(0) : "memory");
|
||||
} else {
|
||||
asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 0), %1)
|
||||
: : "r" (va), "i" (CPU_FTR_ARCH_206)
|
||||
: "memory");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* We need 14 to 14 + i bits of va */
|
||||
@@ -203,9 +208,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize)
|
||||
*/
|
||||
va |= (vpn & 0xfe);
|
||||
va |= 1; /* L */
|
||||
asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 1), %1)
|
||||
: : "r" (va), "i" (CPU_FTR_ARCH_206)
|
||||
: "memory");
|
||||
|
||||
if (cpu_has_feature(CPU_FTR_ARCH_32)) {
|
||||
asm volatile(PPC_TLBIEL(%0, %1, 0, 0, 0) : : "r"(va), "r"(0) : "memory");
|
||||
} else {
|
||||
asm volatile(ASM_FTR_IFSET("tlbiel %0", PPC_TLBIEL_v205(%0, 1), %1)
|
||||
: : "r" (va), "i" (CPU_FTR_ARCH_206)
|
||||
: "memory");
|
||||
}
|
||||
break;
|
||||
}
|
||||
trace_tlbie(0, 1, va, 0, 0, 0, 0);
|
||||
|
||||
@@ -628,7 +628,9 @@ void __init mmu_early_init_devtree(void)
|
||||
|
||||
of_scan_flat_dt(dt_scan_mmu_pid_width, NULL);
|
||||
if (hvmode && !mmu_lpid_bits) {
|
||||
if (early_cpu_has_feature(CPU_FTR_ARCH_207S))
|
||||
if (early_cpu_has_feature(CPU_FTR_ARCH_32))
|
||||
mmu_lpid_bits = 16; /* POWER12 */
|
||||
else if (early_cpu_has_feature(CPU_FTR_ARCH_207S))
|
||||
mmu_lpid_bits = 12; /* POWER8-10 */
|
||||
else
|
||||
mmu_lpid_bits = 10; /* POWER7 */
|
||||
|
||||
Reference in New Issue
Block a user