Re: [PATCH v3 2/2] target/ppc: Add support for scv and rfscv instructions
On Tue, Mar 17, 2020 at 03:49:18PM +1000, Nicholas Piggin wrote: > POWER9 adds scv and rfscv instructions and the system call vectored > interrupt. Linux does not support this instruction yet but it has > been tested with a modified kernel that runs on real hardware. > > Signed-off-by: Nicholas Piggin Applied to ppc-for-5.1. > --- > Since v2: > - Rebased on top of FWNMI series > > linux-user/ppc/cpu_loop.c | 1 + > target/ppc/cpu.h| 7 ++- > target/ppc/excp_helper.c| 98 - > target/ppc/helper.h | 1 + > target/ppc/translate.c | 46 +++- > target/ppc/translate_init.inc.c | 3 +- > 6 files changed, 126 insertions(+), 30 deletions(-) > > diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c > index 5b27f8603e..df71e15a25 100644 > --- a/linux-user/ppc/cpu_loop.c > +++ b/linux-user/ppc/cpu_loop.c > @@ -267,6 +267,7 @@ void cpu_loop(CPUPPCState *env) > queue_signal(env, info.si_signo, QEMU_SI_FAULT, ); > break; > case POWERPC_EXCP_SYSCALL: /* System call exception > */ > +case POWERPC_EXCP_SYSCALL_VECTORED: > cpu_abort(cs, "Syscall exception while in user mode. " >"Aborting\n"); > break; > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h > index ed8d2015bd..992f0a49e8 100644 > --- a/target/ppc/cpu.h > +++ b/target/ppc/cpu.h > @@ -127,8 +127,9 @@ enum { > POWERPC_EXCP_SDOOR_HV = 100, > /* ISA 3.00 additions */ > POWERPC_EXCP_HVIRT= 101, > +POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception > */ > /* EOL > */ > -POWERPC_EXCP_NB = 102, > +POWERPC_EXCP_NB = 103, > /* QEMU exceptions: used internally during code translation > */ > POWERPC_EXCP_STOP = 0x200, /* stop translation > */ > POWERPC_EXCP_BRANCH = 0x201, /* branch instruction > */ > @@ -475,6 +476,7 @@ typedef struct ppc_v3_pate_t { > /* Facility Status and Control (FSCR) bits */ > #define FSCR_EBB(63 - 56) /* Event-Based Branch Facility */ > #define FSCR_TAR(63 - 55) /* Target Address Register */ > +#define FSCR_SCV(63 - 51) /* System call vectored */ > /* Interrupt cause mask and position in FSCR. HFSCR has the same format */ > #define FSCR_IC_MASK(0xFFULL) > #define FSCR_IC_POS (63 - 7) > @@ -484,6 +486,7 @@ typedef struct ppc_v3_pate_t { > #define FSCR_IC_TM 5 > #define FSCR_IC_EBB 7 > #define FSCR_IC_TAR 8 > +#define FSCR_IC_SCV12 > > /* Exception state register bits definition > */ > #define ESR_PIL PPC_BIT(36) /* Illegal Instruction*/ > @@ -551,6 +554,8 @@ enum { > POWERPC_FLAG_VSX = 0x0008, > /* Has Transaction Memory (ISA 2.07) > */ > POWERPC_FLAG_TM = 0x0010, > +/* Has SCV (ISA 3.00) > */ > +POWERPC_FLAG_SCV = 0x0020, > }; > > > /*/ > diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c > index 81ee19ebae..73b5c28d03 100644 > --- a/target/ppc/excp_helper.c > +++ b/target/ppc/excp_helper.c > @@ -67,6 +67,18 @@ static inline void dump_syscall(CPUPPCState *env) >ppc_dump_gpr(env, 8), env->nip); > } > > +static inline void dump_syscall_vectored(CPUPPCState *env) > +{ > +qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 > + " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 > + " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64 > + " nip=" TARGET_FMT_lx "\n", > + ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), > + ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5), > + ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7), > + ppc_dump_gpr(env, 8), env->nip); > +} > + > static inline void dump_hcall(CPUPPCState *env) > { > qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64 > @@ -185,7 +197,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int > excp_model, int excp) > CPUState *cs = CPU(cpu); > CPUPPCState *env = >env; > target_ulong msr, new_msr, vector; > -int srr0, srr1, asrr0, asrr1, lev, ail; > +int srr0, srr1, asrr0, asrr1, lev = -1, ail; > bool lpes0; > > qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx > @@ -421,6 +433,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int > excp_model, int excp) > new_msr |= (target_ulong)MSR_HVB; > } > break; > +case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception
[PATCH v3 2/2] target/ppc: Add support for scv and rfscv instructions
POWER9 adds scv and rfscv instructions and the system call vectored interrupt. Linux does not support this instruction yet but it has been tested with a modified kernel that runs on real hardware. Signed-off-by: Nicholas Piggin --- Since v2: - Rebased on top of FWNMI series linux-user/ppc/cpu_loop.c | 1 + target/ppc/cpu.h| 7 ++- target/ppc/excp_helper.c| 98 - target/ppc/helper.h | 1 + target/ppc/translate.c | 46 +++- target/ppc/translate_init.inc.c | 3 +- 6 files changed, 126 insertions(+), 30 deletions(-) diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c index 5b27f8603e..df71e15a25 100644 --- a/linux-user/ppc/cpu_loop.c +++ b/linux-user/ppc/cpu_loop.c @@ -267,6 +267,7 @@ void cpu_loop(CPUPPCState *env) queue_signal(env, info.si_signo, QEMU_SI_FAULT, ); break; case POWERPC_EXCP_SYSCALL: /* System call exception */ +case POWERPC_EXCP_SYSCALL_VECTORED: cpu_abort(cs, "Syscall exception while in user mode. " "Aborting\n"); break; diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index ed8d2015bd..992f0a49e8 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -127,8 +127,9 @@ enum { POWERPC_EXCP_SDOOR_HV = 100, /* ISA 3.00 additions */ POWERPC_EXCP_HVIRT= 101, +POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception */ /* EOL */ -POWERPC_EXCP_NB = 102, +POWERPC_EXCP_NB = 103, /* QEMU exceptions: used internally during code translation */ POWERPC_EXCP_STOP = 0x200, /* stop translation */ POWERPC_EXCP_BRANCH = 0x201, /* branch instruction */ @@ -475,6 +476,7 @@ typedef struct ppc_v3_pate_t { /* Facility Status and Control (FSCR) bits */ #define FSCR_EBB(63 - 56) /* Event-Based Branch Facility */ #define FSCR_TAR(63 - 55) /* Target Address Register */ +#define FSCR_SCV(63 - 51) /* System call vectored */ /* Interrupt cause mask and position in FSCR. HFSCR has the same format */ #define FSCR_IC_MASK(0xFFULL) #define FSCR_IC_POS (63 - 7) @@ -484,6 +486,7 @@ typedef struct ppc_v3_pate_t { #define FSCR_IC_TM 5 #define FSCR_IC_EBB 7 #define FSCR_IC_TAR 8 +#define FSCR_IC_SCV12 /* Exception state register bits definition */ #define ESR_PIL PPC_BIT(36) /* Illegal Instruction*/ @@ -551,6 +554,8 @@ enum { POWERPC_FLAG_VSX = 0x0008, /* Has Transaction Memory (ISA 2.07) */ POWERPC_FLAG_TM = 0x0010, +/* Has SCV (ISA 3.00)*/ +POWERPC_FLAG_SCV = 0x0020, }; /*/ diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 81ee19ebae..73b5c28d03 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -67,6 +67,18 @@ static inline void dump_syscall(CPUPPCState *env) ppc_dump_gpr(env, 8), env->nip); } +static inline void dump_syscall_vectored(CPUPPCState *env) +{ +qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 + " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 + " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64 + " nip=" TARGET_FMT_lx "\n", + ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), + ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5), + ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7), + ppc_dump_gpr(env, 8), env->nip); +} + static inline void dump_hcall(CPUPPCState *env) { qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64 @@ -185,7 +197,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) CPUState *cs = CPU(cpu); CPUPPCState *env = >env; target_ulong msr, new_msr, vector; -int srr0, srr1, asrr0, asrr1, lev, ail; +int srr0, srr1, asrr0, asrr1, lev = -1, ail; bool lpes0; qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx @@ -421,6 +433,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) new_msr |= (target_ulong)MSR_HVB; } break; +case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ +lev = env->error_code; +dump_syscall_vectored(env); +env->nip += 4; +new_msr |= env->msr & ((target_ulong)1 << MSR_EE); +new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +break; case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ case