target-sparc: implement UA2005 GL register

Backports commit cbc3a6a4cc675516328a2b0d3602355d68b6302d from qemu
This commit is contained in:
Artyom Tarasenko 2018-03-01 21:07:32 -05:00 committed by Lioncash
parent 05e80b59af
commit 0a124b2199
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
9 changed files with 67 additions and 7 deletions

View file

@ -4491,6 +4491,7 @@ sparc_symbols = (
'helper_taddcctv', 'helper_taddcctv',
'helper_tsubcctv', 'helper_tsubcctv',
'helper_udiv_cc', 'helper_udiv_cc',
'helper_wrgl',
'sparc_cpu_do_interrupt', 'sparc_cpu_do_interrupt',
'sparc_cpu_do_unaligned_access', 'sparc_cpu_do_unaligned_access',
'sparc_cpu_get_phys_page_debug', 'sparc_cpu_get_phys_page_debug',

View file

@ -3483,6 +3483,7 @@
#define helper_taddcctv helper_taddcctv_sparc #define helper_taddcctv helper_taddcctv_sparc
#define helper_tsubcctv helper_tsubcctv_sparc #define helper_tsubcctv helper_tsubcctv_sparc
#define helper_udiv_cc helper_udiv_cc_sparc #define helper_udiv_cc helper_udiv_cc_sparc
#define helper_wrgl helper_wrgl_sparc
#define sparc_cpu_do_interrupt sparc_cpu_do_interrupt_sparc #define sparc_cpu_do_interrupt sparc_cpu_do_interrupt_sparc
#define sparc_cpu_do_unaligned_access sparc_cpu_do_unaligned_access_sparc #define sparc_cpu_do_unaligned_access sparc_cpu_do_unaligned_access_sparc
#define sparc_cpu_get_phys_page_debug sparc_cpu_get_phys_page_debug_sparc #define sparc_cpu_get_phys_page_debug sparc_cpu_get_phys_page_debug_sparc

View file

@ -3483,6 +3483,7 @@
#define helper_taddcctv helper_taddcctv_sparc64 #define helper_taddcctv helper_taddcctv_sparc64
#define helper_tsubcctv helper_tsubcctv_sparc64 #define helper_tsubcctv helper_tsubcctv_sparc64
#define helper_udiv_cc helper_udiv_cc_sparc64 #define helper_udiv_cc helper_udiv_cc_sparc64
#define helper_wrgl helper_wrgl_sparc64
#define sparc_cpu_do_interrupt sparc_cpu_do_interrupt_sparc64 #define sparc_cpu_do_interrupt sparc_cpu_do_interrupt_sparc64
#define sparc_cpu_do_unaligned_access sparc_cpu_do_unaligned_access_sparc64 #define sparc_cpu_do_unaligned_access sparc_cpu_do_unaligned_access_sparc64
#define sparc_cpu_get_phys_page_debug sparc_cpu_get_phys_page_debug_sparc64 #define sparc_cpu_get_phys_page_debug sparc_cpu_get_phys_page_debug_sparc64

View file

@ -57,9 +57,13 @@ static void sparc_cpu_reset(CPUState *s)
env->psrps = 1; env->psrps = 1;
#endif #endif
#ifdef TARGET_SPARC64 #ifdef TARGET_SPARC64
env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG; env->pstate = PS_PRIV | PS_RED | PS_PEF;
if (!cpu_has_hypervisor(env)) {
env->pstate |= PS_AG;
}
env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0; env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
env->tl = env->maxtl; env->tl = env->maxtl;
env->gl = 2;
cpu_tsptr(env)->tt = TT_POWER_ON_RESET; cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
env->lsu = 0; env->lsu = 0;
#else #else
@ -780,14 +784,17 @@ void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT); cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
cpu_fprintf(f, " xcc: "); cpu_fprintf(f, " xcc: ");
cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4)); cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl, cpu_fprintf(f, ") asi: %02x tl: %d pil: %x gl: %d\n", env->asi, env->tl,
env->psrpil); env->psrpil, env->gl);
cpu_fprintf(f, "tbr: " TARGET_FMT_lx " hpstate: " TARGET_FMT_lx " htba: "
TARGET_FMT_lx "\n", env->tbr, env->hpstate, env->htba);
cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d " cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
"cleanwin: %d cwp: %d\n", "cleanwin: %d cwp: %d\n",
env->cansave, env->canrestore, env->otherwin, env->wstate, env->cansave, env->canrestore, env->otherwin, env->wstate,
env->cleanwin, env->nwindows - 1 - env->cwp); env->cleanwin, env->nwindows - 1 - env->cwp);
cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: " cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs); TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
#else #else
cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env)); cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env)); cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));

View file

@ -509,6 +509,7 @@ struct CPUSPARCState {
uint64_t bgregs[8]; /* backup for normal global registers */ uint64_t bgregs[8]; /* backup for normal global registers */
uint64_t igregs[8]; /* interrupt general registers */ uint64_t igregs[8]; /* interrupt general registers */
uint64_t mgregs[8]; /* mmu general registers */ uint64_t mgregs[8]; /* mmu general registers */
uint64_t glregs[8 * MAXTL_MAX];
uint64_t fprs; uint64_t fprs;
uint64_t tick_cmpr, stick_cmpr; uint64_t tick_cmpr, stick_cmpr;
CPUTimer *tick, *stick; CPUTimer *tick, *stick;
@ -607,6 +608,7 @@ void cpu_put_ccr(CPUSPARCState *env1, target_ulong val);
target_ulong cpu_get_cwp64(CPUSPARCState *env1); target_ulong cpu_get_cwp64(CPUSPARCState *env1);
void cpu_put_cwp64(CPUSPARCState *env1, int cwp); void cpu_put_cwp64(CPUSPARCState *env1, int cwp);
void cpu_change_pstate(CPUSPARCState *env1, uint32_t new_pstate); void cpu_change_pstate(CPUSPARCState *env1, uint32_t new_pstate);
void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl);
#endif #endif
int cpu_cwp_inc(CPUSPARCState *env1, int cwp); int cpu_cwp_inc(CPUSPARCState *env1, int cwp);
int cpu_cwp_dec(CPUSPARCState *env1, int cwp); int cpu_cwp_dec(CPUSPARCState *env1, int cwp);

View file

@ -7,6 +7,7 @@ DEF_HELPER_2(wrpsr, void, env, tl)
DEF_HELPER_1(rdpsr, tl, env) DEF_HELPER_1(rdpsr, tl, env)
#else #else
DEF_HELPER_FLAGS_2(wrpil, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_2(wrpil, TCG_CALL_NO_RWG, void, env, tl)
DEF_HELPER_2(wrgl, void, env, tl)
DEF_HELPER_2(wrpstate, void, env, tl) DEF_HELPER_2(wrpstate, void, env, tl)
DEF_HELPER_1(done, void, env) DEF_HELPER_1(done, void, env)
DEF_HELPER_1(retry, void, env) DEF_HELPER_1(retry, void, env)

View file

@ -66,6 +66,12 @@ void sparc_cpu_do_interrupt(CPUState *cs)
} }
} }
if (env->def->features & CPU_FEATURE_GL) {
tsptr->tstate |= (env->gl & 7ULL) << 40;
cpu_gl_switch_gregs(env, env->gl + 1);
env->gl++;
}
switch (intno) { switch (intno) {
case TT_IVEC: case TT_IVEC:
if (!cpu_has_hypervisor(env)) { if (!cpu_has_hypervisor(env)) {

View file

@ -4760,8 +4760,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins
break; break;
case 16: // UA2005 gl case 16: // UA2005 gl
CHECK_IU_FEATURE(dc, GL); CHECK_IU_FEATURE(dc, GL);
tcg_gen_st32_tl(tcg_ctx, cpu_tmp0, tcg_ctx->cpu_env, gen_helper_wrgl(tcg_ctx, tcg_ctx->cpu_env, cpu_tmp0);
offsetof(CPUSPARCState, gl));
break; break;
case 26: // UA2005 strand status case 26: // UA2005 strand status
CHECK_IU_FEATURE(dc, HYPV); CHECK_IU_FEATURE(dc, HYPV);

View file

@ -291,6 +291,10 @@ void helper_wrcwp(CPUSPARCState *env, target_ulong new_cwp)
static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate) static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate)
{ {
if (env->def->features & CPU_FEATURE_GL) {
return env->glregs + (env->gl & 7) * 8;
}
switch (pstate) { switch (pstate) {
default: default:
//trace_win_helper_gregset_error(pstate); //trace_win_helper_gregset_error(pstate);
@ -306,14 +310,40 @@ static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate)
} }
} }
static inline uint64_t *get_gl_gregset(CPUSPARCState *env, uint32_t gl)
{
return env->glregs + (gl & 7) * 8;
}
/* Switch global register bank */
void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl)
{
uint64_t *src, *dst;
src = get_gl_gregset(env, new_gl);
dst = get_gl_gregset(env, env->gl);
if (src != dst) {
memcpy32(dst, env->gregs);
memcpy32(env->gregs, src);
}
}
void helper_wrgl(CPUSPARCState *env, target_ulong new_gl)
{
cpu_gl_switch_gregs(env, new_gl & 7);
env->gl = new_gl & 7;
}
void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate) void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate)
{ {
uint32_t pstate_regs, new_pstate_regs; uint32_t pstate_regs, new_pstate_regs;
uint64_t *src, *dst; uint64_t *src, *dst;
if (env->def->features & CPU_FEATURE_GL) { if (env->def->features & CPU_FEATURE_GL) {
/* PS_AG is not implemented in this case */ /* PS_AG, IG and MG are not implemented in this case */
new_pstate &= ~PS_AG; new_pstate &= ~(PS_AG | PS_IG | PS_MG);
env->pstate = new_pstate;
return;
} }
pstate_regs = env->pstate & 0xc01; pstate_regs = env->pstate & 0xc01;
@ -367,6 +397,12 @@ void helper_done(CPUSPARCState *env)
env->asi = (tsptr->tstate >> 24) & 0xff; env->asi = (tsptr->tstate >> 24) & 0xff;
cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f);
cpu_put_cwp64(env, tsptr->tstate & 0xff); cpu_put_cwp64(env, tsptr->tstate & 0xff);
if (cpu_has_hypervisor(env)) {
uint32_t new_gl = (tsptr->tstate >> 40) & 7;
env->hpstate = env->htstate[env->tl];
cpu_gl_switch_gregs(env, new_gl);
env->gl = new_gl;
}
env->tl--; env->tl--;
//trace_win_helper_done(env->tl); //trace_win_helper_done(env->tl);
@ -388,6 +424,12 @@ void helper_retry(CPUSPARCState *env)
env->asi = (tsptr->tstate >> 24) & 0xff; env->asi = (tsptr->tstate >> 24) & 0xff;
cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f); cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f);
cpu_put_cwp64(env, tsptr->tstate & 0xff); cpu_put_cwp64(env, tsptr->tstate & 0xff);
if (cpu_has_hypervisor(env)) {
uint32_t new_gl = (tsptr->tstate >> 40) & 7;
env->hpstate = env->htstate[env->tl];
cpu_gl_switch_gregs(env, new_gl);
env->gl = new_gl;
}
env->tl--; env->tl--;
//trace_win_helper_retry(env->tl); //trace_win_helper_retry(env->tl);