mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
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
6 changed files with 133 additions and 30 deletions
|
@ -173,6 +173,7 @@ struct DisasContext {
|
|||
bool vsx_enabled;
|
||||
bool spe_enabled;
|
||||
bool tm_enabled;
|
||||
bool scv_enabled;
|
||||
bool gtse;
|
||||
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
|
||||
int singlestep_enabled;
|
||||
|
@ -4030,6 +4031,24 @@ static void gen_rfid(DisasContext *ctx)
|
|||
#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)
|
||||
{
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
|
@ -4048,6 +4067,7 @@ static void gen_hrfid(DisasContext *ctx)
|
|||
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
|
||||
#else
|
||||
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
|
||||
#define POWERPC_SYSCALL_VECTORED POWERPC_EXCP_SYSCALL_VECTORED
|
||||
#endif
|
||||
static void gen_sc(DisasContext *ctx)
|
||||
{
|
||||
|
@ -4057,6 +4077,23 @@ static void gen_sc(DisasContext *ctx)
|
|||
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 ***/
|
||||
|
||||
/* 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),
|
||||
#if defined(TARGET_PPC64)
|
||||
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(doze, 0x13, 0x12, 0x0c, 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(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
|
||||
#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(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
|
||||
#if defined(TARGET_PPC64)
|
||||
|
@ -7835,6 +7880,12 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
|||
} else {
|
||||
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 ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
|
||||
ctx->tm_enabled = !!msr_tm;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue