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 <npiggin@gmail.com> Message-Id: <20200507115328.789175-1-npiggin@gmail.com> [dwg: Corrected an overlong line] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
ececb880d6
commit
3c89b8d6ac
@ -267,6 +267,7 @@ void cpu_loop(CPUPPCState *env)
|
|||||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||||
break;
|
break;
|
||||||
case POWERPC_EXCP_SYSCALL: /* System call exception */
|
case POWERPC_EXCP_SYSCALL: /* System call exception */
|
||||||
|
case POWERPC_EXCP_SYSCALL_VECTORED:
|
||||||
cpu_abort(cs, "Syscall exception while in user mode. "
|
cpu_abort(cs, "Syscall exception while in user mode. "
|
||||||
"Aborting\n");
|
"Aborting\n");
|
||||||
break;
|
break;
|
||||||
|
@ -127,8 +127,9 @@ enum {
|
|||||||
POWERPC_EXCP_SDOOR_HV = 100,
|
POWERPC_EXCP_SDOOR_HV = 100,
|
||||||
/* ISA 3.00 additions */
|
/* ISA 3.00 additions */
|
||||||
POWERPC_EXCP_HVIRT = 101,
|
POWERPC_EXCP_HVIRT = 101,
|
||||||
|
POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception */
|
||||||
/* EOL */
|
/* EOL */
|
||||||
POWERPC_EXCP_NB = 102,
|
POWERPC_EXCP_NB = 103,
|
||||||
/* QEMU exceptions: used internally during code translation */
|
/* QEMU exceptions: used internally during code translation */
|
||||||
POWERPC_EXCP_STOP = 0x200, /* stop translation */
|
POWERPC_EXCP_STOP = 0x200, /* stop translation */
|
||||||
POWERPC_EXCP_BRANCH = 0x201, /* branch instruction */
|
POWERPC_EXCP_BRANCH = 0x201, /* branch instruction */
|
||||||
@ -478,6 +479,7 @@ typedef struct ppc_v3_pate_t {
|
|||||||
/* Facility Status and Control (FSCR) bits */
|
/* Facility Status and Control (FSCR) bits */
|
||||||
#define FSCR_EBB (63 - 56) /* Event-Based Branch Facility */
|
#define FSCR_EBB (63 - 56) /* Event-Based Branch Facility */
|
||||||
#define FSCR_TAR (63 - 55) /* Target Address Register */
|
#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 */
|
/* Interrupt cause mask and position in FSCR. HFSCR has the same format */
|
||||||
#define FSCR_IC_MASK (0xFFULL)
|
#define FSCR_IC_MASK (0xFFULL)
|
||||||
#define FSCR_IC_POS (63 - 7)
|
#define FSCR_IC_POS (63 - 7)
|
||||||
@ -487,6 +489,7 @@ typedef struct ppc_v3_pate_t {
|
|||||||
#define FSCR_IC_TM 5
|
#define FSCR_IC_TM 5
|
||||||
#define FSCR_IC_EBB 7
|
#define FSCR_IC_EBB 7
|
||||||
#define FSCR_IC_TAR 8
|
#define FSCR_IC_TAR 8
|
||||||
|
#define FSCR_IC_SCV 12
|
||||||
|
|
||||||
/* Exception state register bits definition */
|
/* Exception state register bits definition */
|
||||||
#define ESR_PIL PPC_BIT(36) /* Illegal Instruction */
|
#define ESR_PIL PPC_BIT(36) /* Illegal Instruction */
|
||||||
@ -554,6 +557,8 @@ enum {
|
|||||||
POWERPC_FLAG_VSX = 0x00080000,
|
POWERPC_FLAG_VSX = 0x00080000,
|
||||||
/* Has Transaction Memory (ISA 2.07) */
|
/* Has Transaction Memory (ISA 2.07) */
|
||||||
POWERPC_FLAG_TM = 0x00100000,
|
POWERPC_FLAG_TM = 0x00100000,
|
||||||
|
/* Has SCV (ISA 3.00) */
|
||||||
|
POWERPC_FLAG_SCV = 0x00200000,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -67,6 +67,18 @@ static inline void dump_syscall(CPUPPCState *env)
|
|||||||
ppc_dump_gpr(env, 8), env->nip);
|
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)
|
static inline void dump_hcall(CPUPPCState *env)
|
||||||
{
|
{
|
||||||
qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64
|
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);
|
CPUState *cs = CPU(cpu);
|
||||||
CPUPPCState *env = &cpu->env;
|
CPUPPCState *env = &cpu->env;
|
||||||
target_ulong msr, new_msr, vector;
|
target_ulong msr, new_msr, vector;
|
||||||
int srr0, srr1, asrr0, asrr1, lev, ail;
|
int srr0, srr1, asrr0, asrr1, lev = -1, ail;
|
||||||
bool lpes0;
|
bool lpes0;
|
||||||
|
|
||||||
qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
|
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;
|
new_msr |= (target_ulong)MSR_HVB;
|
||||||
}
|
}
|
||||||
break;
|
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 POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
|
||||||
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
|
case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
|
||||||
case POWERPC_EXCP_DECR: /* Decrementer exception */
|
case POWERPC_EXCP_DECR: /* Decrementer exception */
|
||||||
@ -724,12 +743,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save PC */
|
|
||||||
env->spr[srr0] = env->nip;
|
|
||||||
|
|
||||||
/* Save MSR */
|
|
||||||
env->spr[srr1] = msr;
|
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if (!(env->msr_mask & MSR_HVB)) {
|
if (!(env->msr_mask & MSR_HVB)) {
|
||||||
if (new_msr & MSR_HVB) {
|
if (new_msr & MSR_HVB) {
|
||||||
@ -742,14 +755,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If any alternate SRR register are defined, duplicate saved values */
|
|
||||||
if (asrr0 != -1) {
|
|
||||||
env->spr[asrr0] = env->spr[srr0];
|
|
||||||
}
|
|
||||||
if (asrr1 != -1) {
|
|
||||||
env->spr[asrr1] = env->spr[srr1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sort out endianness of interrupt, this differs depending on the
|
* Sort out endianness of interrupt, this differs depending on the
|
||||||
* CPU, the HV mode, etc...
|
* CPU, the HV mode, etc...
|
||||||
@ -784,14 +789,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Jump to handler */
|
|
||||||
vector = env->excp_vectors[excp];
|
|
||||||
if (vector == (target_ulong)-1ULL) {
|
|
||||||
cpu_abort(cs, "Raised an exception without defined vector %d\n",
|
|
||||||
excp);
|
|
||||||
}
|
|
||||||
vector |= env->excp_prefix;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AIL only works if there is no HV transition and we are running
|
* AIL only works if there is no HV transition and we are running
|
||||||
* with translations enabled
|
* with translations enabled
|
||||||
@ -800,10 +797,21 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||||||
((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
|
((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
|
||||||
ail = 0;
|
ail = 0;
|
||||||
}
|
}
|
||||||
/* Handle AIL */
|
|
||||||
if (ail) {
|
vector = env->excp_vectors[excp];
|
||||||
new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
|
if (vector == (target_ulong)-1ULL) {
|
||||||
vector |= ppc_excp_vector_offset(cs, ail);
|
cpu_abort(cs, "Raised an exception without defined vector %d\n",
|
||||||
|
excp);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector |= env->excp_prefix;
|
||||||
|
|
||||||
|
/* If any alternate SRR register are defined, duplicate saved values */
|
||||||
|
if (asrr0 != -1) {
|
||||||
|
env->spr[asrr0] = env->nip;
|
||||||
|
}
|
||||||
|
if (asrr1 != -1) {
|
||||||
|
env->spr[asrr1] = msr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
@ -823,6 +831,37 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (excp != POWERPC_EXCP_SYSCALL_VECTORED) {
|
||||||
|
/* Save PC */
|
||||||
|
env->spr[srr0] = env->nip;
|
||||||
|
|
||||||
|
/* Save MSR */
|
||||||
|
env->spr[srr1] = msr;
|
||||||
|
|
||||||
|
/* Handle AIL */
|
||||||
|
if (ail) {
|
||||||
|
new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
|
||||||
|
vector |= ppc_excp_vector_offset(cs, ail);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(TARGET_PPC64)
|
||||||
|
} else {
|
||||||
|
/* scv AIL is a little different */
|
||||||
|
if (ail) {
|
||||||
|
new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
|
||||||
|
}
|
||||||
|
if (ail == AIL_C000_0000_0000_4000) {
|
||||||
|
vector |= 0xc000000000003000ull;
|
||||||
|
} else {
|
||||||
|
vector |= 0x0000000000017000ull;
|
||||||
|
}
|
||||||
|
vector += lev * 0x20;
|
||||||
|
|
||||||
|
env->lr = env->nip;
|
||||||
|
env->ctr = msr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
powerpc_set_excp_state(cpu, vector, new_msr);
|
powerpc_set_excp_state(cpu, vector, new_msr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1160,6 +1199,11 @@ void helper_rfid(CPUPPCState *env)
|
|||||||
do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
|
do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void helper_rfscv(CPUPPCState *env)
|
||||||
|
{
|
||||||
|
do_rfi(env, env->lr, env->ctr);
|
||||||
|
}
|
||||||
|
|
||||||
void helper_hrfid(CPUPPCState *env)
|
void helper_hrfid(CPUPPCState *env)
|
||||||
{
|
{
|
||||||
do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
|
do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
|
||||||
|
@ -15,6 +15,7 @@ DEF_HELPER_1(rfmci, void, env)
|
|||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
DEF_HELPER_2(pminsn, void, env, i32)
|
DEF_HELPER_2(pminsn, void, env, i32)
|
||||||
DEF_HELPER_1(rfid, void, env)
|
DEF_HELPER_1(rfid, void, env)
|
||||||
|
DEF_HELPER_1(rfscv, void, env)
|
||||||
DEF_HELPER_1(hrfid, void, env)
|
DEF_HELPER_1(hrfid, void, env)
|
||||||
DEF_HELPER_2(store_lpcr, void, env, tl)
|
DEF_HELPER_2(store_lpcr, void, env, tl)
|
||||||
DEF_HELPER_2(store_pcr, void, env, tl)
|
DEF_HELPER_2(store_pcr, void, env, tl)
|
||||||
|
@ -173,6 +173,7 @@ struct DisasContext {
|
|||||||
bool vsx_enabled;
|
bool vsx_enabled;
|
||||||
bool spe_enabled;
|
bool spe_enabled;
|
||||||
bool tm_enabled;
|
bool tm_enabled;
|
||||||
|
bool scv_enabled;
|
||||||
bool gtse;
|
bool gtse;
|
||||||
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
|
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
|
||||||
int singlestep_enabled;
|
int singlestep_enabled;
|
||||||
@ -4030,6 +4031,24 @@ static void gen_rfid(DisasContext *ctx)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
static void gen_rfscv(DisasContext *ctx)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_USER_ONLY)
|
||||||
|
GEN_PRIV;
|
||||||
|
#else
|
||||||
|
/* Restore CPU state */
|
||||||
|
CHK_SV;
|
||||||
|
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
|
||||||
|
gen_io_start();
|
||||||
|
}
|
||||||
|
gen_update_cfar(ctx, ctx->base.pc_next - 4);
|
||||||
|
gen_helper_rfscv(cpu_env);
|
||||||
|
gen_sync_exception(ctx);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void gen_hrfid(DisasContext *ctx)
|
static void gen_hrfid(DisasContext *ctx)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
@ -4048,6 +4067,7 @@ static void gen_hrfid(DisasContext *ctx)
|
|||||||
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
|
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
|
||||||
#else
|
#else
|
||||||
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
|
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
|
||||||
|
#define POWERPC_SYSCALL_VECTORED POWERPC_EXCP_SYSCALL_VECTORED
|
||||||
#endif
|
#endif
|
||||||
static void gen_sc(DisasContext *ctx)
|
static void gen_sc(DisasContext *ctx)
|
||||||
{
|
{
|
||||||
@ -4057,6 +4077,23 @@ static void gen_sc(DisasContext *ctx)
|
|||||||
gen_exception_err(ctx, POWERPC_SYSCALL, lev);
|
gen_exception_err(ctx, POWERPC_SYSCALL, lev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(TARGET_PPC64)
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
static void gen_scv(DisasContext *ctx)
|
||||||
|
{
|
||||||
|
uint32_t lev;
|
||||||
|
|
||||||
|
if (unlikely(!ctx->scv_enabled)) {
|
||||||
|
gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_SCV);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lev = (ctx->opcode >> 5) & 0x7F;
|
||||||
|
gen_exception_err(ctx, POWERPC_SYSCALL_VECTORED, lev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*** Trap ***/
|
/*** Trap ***/
|
||||||
|
|
||||||
/* Check for unconditional traps (always or never) */
|
/* Check for unconditional traps (always or never) */
|
||||||
@ -7049,6 +7086,12 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
|
|||||||
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
|
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
|
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
|
||||||
|
GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
|
||||||
|
GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
|
||||||
|
GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300),
|
||||||
|
#endif
|
||||||
GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
|
GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
|
||||||
GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
|
GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
|
||||||
GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
|
GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
|
||||||
@ -7056,7 +7099,9 @@ GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
|
|||||||
GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
|
GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
|
||||||
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
|
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
|
||||||
#endif
|
#endif
|
||||||
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
|
/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
|
||||||
|
GEN_HANDLER(sc, 0x11, 0x11, 0xFF, 0x03FFF01D, PPC_FLOW),
|
||||||
|
GEN_HANDLER(sc, 0x11, 0x01, 0xFF, 0x03FFF01D, PPC_FLOW),
|
||||||
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
|
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
|
||||||
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
|
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
@ -7835,6 +7880,12 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
|||||||
} else {
|
} else {
|
||||||
ctx->vsx_enabled = false;
|
ctx->vsx_enabled = false;
|
||||||
}
|
}
|
||||||
|
if ((env->flags & POWERPC_FLAG_SCV)
|
||||||
|
&& (env->spr[SPR_FSCR] & (1ull << FSCR_SCV))) {
|
||||||
|
ctx->scv_enabled = true;
|
||||||
|
} else {
|
||||||
|
ctx->scv_enabled = false;
|
||||||
|
}
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
|
if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
|
||||||
ctx->tm_enabled = !!msr_tm;
|
ctx->tm_enabled = !!msr_tm;
|
||||||
|
@ -3382,6 +3382,7 @@ static void init_excp_POWER9(CPUPPCState *env)
|
|||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0;
|
env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0;
|
||||||
|
env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00000000;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9030,7 +9031,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
|
|||||||
pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
|
pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
|
||||||
POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
|
POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
|
||||||
POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
|
POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
|
||||||
POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
|
POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV;
|
||||||
pcc->l1_dcache_size = 0x8000;
|
pcc->l1_dcache_size = 0x8000;
|
||||||
pcc->l1_icache_size = 0x8000;
|
pcc->l1_icache_size = 0x8000;
|
||||||
pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
|
pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
|
||||||
|
Loading…
Reference in New Issue
Block a user