* [Qemu-devel] [PATCH] sparc64 replace tsptr with helper routine
@ 2009-07-19 21:19 Igor Kovalenko
2009-07-20 6:49 ` Blue Swirl
0 siblings, 1 reply; 4+ messages in thread
From: Igor Kovalenko @ 2009-07-19 21:19 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 435 bytes --]
tl and tsptr of members sparc64 cpu state must be changed
simultaneously to keep trap state window in sync with current
trap level. Currently translation of store to tl does not change
tsptr, which leads to corrupt trap state on corresponding
trap level.
This patch removes tsptr from sparc64 cpu state and replaces
all uses with call to helper routine.
Signed-off-by: igor.v.kovalenko@gmail.com
--
Kind regards,
Igor V. Kovalenko
[-- Attachment #2: sparc64-tsptr-tl --]
[-- Type: application/octet-stream, Size: 10396 bytes --]
Index: qemu-trunk/target-sparc/cpu.h
===================================================================
--- qemu-trunk.orig/target-sparc/cpu.h
+++ qemu-trunk/target-sparc/cpu.h
@@ -340,7 +340,6 @@ typedef struct CPUSPARCState {
#if defined(TARGET_SPARC64)
#define MAXTL_MAX 8
#define MAXTL_MASK (MAXTL_MAX - 1)
- trap_state *tsptr;
trap_state ts[MAXTL_MAX];
uint32_t xcc; /* Extended integer condition codes */
uint32_t asi;
@@ -556,6 +555,7 @@ void cpu_check_irqs(CPUSPARCState *env);
void cpu_tick_set_count(void *opaque, uint64_t count);
uint64_t cpu_tick_get_count(void *opaque);
void cpu_tick_set_limit(void *opaque, uint64_t limit);
+trap_state* cpu_tsptr(CPUState* env);
#endif
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
Index: qemu-trunk/target-sparc/helper.h
===================================================================
--- qemu-trunk.orig/target-sparc/helper.h
+++ qemu-trunk/target-sparc/helper.h
@@ -5,6 +5,7 @@ DEF_HELPER_0(rett, void)
DEF_HELPER_1(wrpsr, void, tl)
DEF_HELPER_0(rdpsr, tl)
#else
+DEF_HELPER_1(get_tsptr, ptr, ptr)
DEF_HELPER_1(wrpstate, void, tl)
DEF_HELPER_0(done, void)
DEF_HELPER_0(retry, void)
Index: qemu-trunk/target-sparc/translate.c
===================================================================
--- qemu-trunk.orig/target-sparc/translate.c
+++ qemu-trunk/target-sparc/translate.c
@@ -1978,10 +1978,11 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
+
tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tpc));
+
tcg_temp_free_ptr(r_tsptr);
}
break;
@@ -1990,8 +1991,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tnpc));
tcg_temp_free_ptr(r_tsptr);
@@ -2002,8 +2002,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tstate));
tcg_temp_free_ptr(r_tsptr);
@@ -2014,8 +2013,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
offsetof(trap_state, tt));
tcg_temp_free_ptr(r_tsptr);
@@ -3271,8 +3269,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tpc));
tcg_temp_free_ptr(r_tsptr);
@@ -3283,8 +3280,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tnpc));
tcg_temp_free_ptr(r_tsptr);
@@ -3295,8 +3291,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state,
tstate));
@@ -3308,8 +3303,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
tcg_gen_st_i32(cpu_tmp32, r_tsptr,
offsetof(trap_state, tt));
Index: qemu-trunk/target-sparc/op_helper.c
===================================================================
--- qemu-trunk.orig/target-sparc/op_helper.c
+++ qemu-trunk/target-sparc/op_helper.c
@@ -3248,28 +3248,35 @@ void helper_wrpstate(target_ulong new_st
change_pstate(new_state & 0xf3f);
}
+void* helper_get_tsptr(void *opaque)
+{
+ return cpu_tsptr(opaque);
+}
+
void helper_done(void)
{
- env->pc = env->tsptr->tpc;
- env->npc = env->tsptr->tnpc + 4;
- PUT_CCR(env, env->tsptr->tstate >> 32);
- env->asi = (env->tsptr->tstate >> 24) & 0xff;
- change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
- PUT_CWP64(env, env->tsptr->tstate & 0xff);
+ trap_state* tsptr = cpu_tsptr(env);
+
+ env->pc = tsptr->tpc;
+ env->npc = tsptr->tnpc + 4;
+ PUT_CCR(env, tsptr->tstate >> 32);
+ env->asi = (tsptr->tstate >> 24) & 0xff;
+ change_pstate((tsptr->tstate >> 8) & 0xf3f);
+ PUT_CWP64(env, tsptr->tstate & 0xff);
env->tl--;
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
}
void helper_retry(void)
{
- env->pc = env->tsptr->tpc;
- env->npc = env->tsptr->tnpc;
- PUT_CCR(env, env->tsptr->tstate >> 32);
- env->asi = (env->tsptr->tstate >> 24) & 0xff;
- change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
- PUT_CWP64(env, env->tsptr->tstate & 0xff);
+ trap_state* tsptr = cpu_tsptr(env);
+
+ env->pc = tsptr->tpc;
+ env->npc = tsptr->tnpc;
+ PUT_CCR(env, tsptr->tstate >> 32);
+ env->asi = (tsptr->tstate >> 24) & 0xff;
+ change_pstate((tsptr->tstate >> 8) & 0xf3f);
+ PUT_CWP64(env, tsptr->tstate & 0xff);
env->tl--;
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
}
void helper_set_softint(uint64_t value)
@@ -3331,9 +3338,15 @@ static const char * const excp_names[0x8
};
#endif
+trap_state* cpu_tsptr(CPUState* env)
+{
+ return &env->ts[env->tl & MAXTL_MASK];
+}
+
void do_interrupt(CPUState *env)
{
int intno = env->exception_index;
+ trap_state* tsptr;
#ifdef DEBUG_PCALL
if (qemu_loglevel_mask(CPU_LOG_INT)) {
@@ -3390,13 +3403,14 @@ void do_interrupt(CPUState *env)
if (env->tl < env->maxtl)
env->tl++;
}
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
- env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
+ tsptr = cpu_tsptr(env);
+
+ tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
GET_CWP64(env);
- env->tsptr->tpc = env->pc;
- env->tsptr->tnpc = env->npc;
- env->tsptr->tt = intno;
+ tsptr->tpc = env->pc;
+ tsptr->tnpc = env->npc;
+ tsptr->tt = intno;
switch (intno) {
case TT_IVEC:
Index: qemu-trunk/target-sparc/helper.c
===================================================================
--- qemu-trunk.orig/target-sparc/helper.c
+++ qemu-trunk/target-sparc/helper.c
@@ -687,7 +687,7 @@ void cpu_reset(CPUSPARCState *env)
#ifdef TARGET_SPARC64
env->pstate = PS_PRIV;
env->hpstate = HS_PRIV;
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
+ env->tl = 0;
env->lsu = 0;
#else
env->mmuregs[0] &= ~(MMU_E | MMU_NF);
Index: qemu-trunk/target-sparc/machine.c
===================================================================
--- qemu-trunk.orig/target-sparc/machine.c
+++ qemu-trunk/target-sparc/machine.c
@@ -164,7 +164,6 @@ int cpu_load(QEMUFile *f, void *opaque,
qemu_get_be32s(f, &env->asi);
qemu_get_be32s(f, &env->pstate);
qemu_get_be32s(f, &env->tl);
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
qemu_get_be32s(f, &env->cansave);
qemu_get_be32s(f, &env->canrestore);
qemu_get_be32s(f, &env->otherwin);
Index: qemu-trunk/linux-user/main.c
===================================================================
--- qemu-trunk.orig/linux-user/main.c
+++ qemu-trunk/linux-user/main.c
@@ -962,7 +962,7 @@ void cpu_loop (CPUSPARCState *env)
if (trapnr == TT_DFAULT)
info._sifields._sigfault._addr = env->dmmuregs[4];
else
- info._sifields._sigfault._addr = env->tsptr->tpc;
+ info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
queue_signal(env, info.si_signo, &info);
}
break;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] sparc64 replace tsptr with helper routine
2009-07-19 21:19 [Qemu-devel] [PATCH] sparc64 replace tsptr with helper routine Igor Kovalenko
@ 2009-07-20 6:49 ` Blue Swirl
2009-07-20 19:00 ` Igor Kovalenko
0 siblings, 1 reply; 4+ messages in thread
From: Blue Swirl @ 2009-07-20 6:49 UTC (permalink / raw)
To: Igor Kovalenko; +Cc: qemu-devel
On Mon, Jul 20, 2009 at 12:19 AM, Igor
Kovalenko<igor.v.kovalenko@gmail.com> wrote:
> tl and tsptr of members sparc64 cpu state must be changed
> simultaneously to keep trap state window in sync with current
> trap level. Currently translation of store to tl does not change
> tsptr, which leads to corrupt trap state on corresponding
> trap level.
>
> This patch removes tsptr from sparc64 cpu state and replaces
> all uses with call to helper routine.
I'd rather have the stores to TL fixed instead of introducing a
helper. A new function to set both TL and tsptr may help. Which stores
to TL do not change tsptr?
On CPU reset, TL should be MAXTL for POR and MIN(TL+1, MAXTL) in other
cases but your patch would set it to 0.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] sparc64 replace tsptr with helper routine
2009-07-20 6:49 ` Blue Swirl
@ 2009-07-20 19:00 ` Igor Kovalenko
2009-07-21 7:21 ` Blue Swirl
0 siblings, 1 reply; 4+ messages in thread
From: Igor Kovalenko @ 2009-07-20 19:00 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1360 bytes --]
On Mon, Jul 20, 2009 at 10:49 AM, Blue Swirl<blauwirbel@gmail.com> wrote:
> On Mon, Jul 20, 2009 at 12:19 AM, Igor
> Kovalenko<igor.v.kovalenko@gmail.com> wrote:
>> tl and tsptr of members sparc64 cpu state must be changed
>> simultaneously to keep trap state window in sync with current
>> trap level. Currently translation of store to tl does not change
>> tsptr, which leads to corrupt trap state on corresponding
>> trap level.
>>
>> This patch removes tsptr from sparc64 cpu state and replaces
>> all uses with call to helper routine.
>
> I'd rather have the stores to TL fixed instead of introducing a
> helper. A new function to set both TL and tsptr may help. Which stores
> to TL do not change tsptr?
The problem is with translate.c portion about handling wrpr
(it sets tl only). My idea is that even remote possibility of tsptr
and tl going out of sync guarantees killing one of them. Since
tl is a real register I decided to loose tsptr.
>
> On CPU reset, TL should be MAXTL for POR and MIN(TL+1, MAXTL) in other
> cases but your patch would set it to 0.
Right but please see that original code did not done that either :)
Please see updated patch which additionally sets tl=maxtl.
I decided to populate trap level, trap type and pstate with
power-on reset values since other reset types are not handled yet.
--
Kind regards,
Igor V. Kovalenko
[-- Attachment #2: sparc64-tsptr-tl-2 --]
[-- Type: application/octet-stream, Size: 10736 bytes --]
Index: qemu-trunk/target-sparc/cpu.h
===================================================================
--- qemu-trunk.orig/target-sparc/cpu.h
+++ qemu-trunk/target-sparc/cpu.h
@@ -49,6 +49,7 @@
#define TT_NCP_INSN 0x24
#define TT_TRAP 0x80
#else
+#define TT_POWER_ON_RESET 0x01
#define TT_TFAULT 0x08
#define TT_CODE_ACCESS 0x0a
#define TT_ILL_INSN 0x10
@@ -340,7 +341,6 @@ typedef struct CPUSPARCState {
#if defined(TARGET_SPARC64)
#define MAXTL_MAX 8
#define MAXTL_MASK (MAXTL_MAX - 1)
- trap_state *tsptr;
trap_state ts[MAXTL_MAX];
uint32_t xcc; /* Extended integer condition codes */
uint32_t asi;
@@ -556,6 +556,7 @@ void cpu_check_irqs(CPUSPARCState *env);
void cpu_tick_set_count(void *opaque, uint64_t count);
uint64_t cpu_tick_get_count(void *opaque);
void cpu_tick_set_limit(void *opaque, uint64_t limit);
+trap_state* cpu_tsptr(CPUState* env);
#endif
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
Index: qemu-trunk/target-sparc/helper.h
===================================================================
--- qemu-trunk.orig/target-sparc/helper.h
+++ qemu-trunk/target-sparc/helper.h
@@ -5,6 +5,7 @@ DEF_HELPER_0(rett, void)
DEF_HELPER_1(wrpsr, void, tl)
DEF_HELPER_0(rdpsr, tl)
#else
+DEF_HELPER_1(get_tsptr, ptr, ptr)
DEF_HELPER_1(wrpstate, void, tl)
DEF_HELPER_0(done, void)
DEF_HELPER_0(retry, void)
Index: qemu-trunk/target-sparc/translate.c
===================================================================
--- qemu-trunk.orig/target-sparc/translate.c
+++ qemu-trunk/target-sparc/translate.c
@@ -1978,10 +1978,11 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
+
tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tpc));
+
tcg_temp_free_ptr(r_tsptr);
}
break;
@@ -1990,8 +1991,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tnpc));
tcg_temp_free_ptr(r_tsptr);
@@ -2002,8 +2002,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tstate));
tcg_temp_free_ptr(r_tsptr);
@@ -2014,8 +2013,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
offsetof(trap_state, tt));
tcg_temp_free_ptr(r_tsptr);
@@ -3271,8 +3269,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tpc));
tcg_temp_free_ptr(r_tsptr);
@@ -3283,8 +3280,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tnpc));
tcg_temp_free_ptr(r_tsptr);
@@ -3295,8 +3291,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state,
tstate));
@@ -3308,8 +3303,7 @@ static void disas_sparc_insn(DisasContex
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_helper_get_tsptr(r_tsptr, cpu_env);
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
tcg_gen_st_i32(cpu_tmp32, r_tsptr,
offsetof(trap_state, tt));
Index: qemu-trunk/target-sparc/op_helper.c
===================================================================
--- qemu-trunk.orig/target-sparc/op_helper.c
+++ qemu-trunk/target-sparc/op_helper.c
@@ -3248,28 +3248,35 @@ void helper_wrpstate(target_ulong new_st
change_pstate(new_state & 0xf3f);
}
+void* helper_get_tsptr(void *opaque)
+{
+ return cpu_tsptr(opaque);
+}
+
void helper_done(void)
{
- env->pc = env->tsptr->tpc;
- env->npc = env->tsptr->tnpc + 4;
- PUT_CCR(env, env->tsptr->tstate >> 32);
- env->asi = (env->tsptr->tstate >> 24) & 0xff;
- change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
- PUT_CWP64(env, env->tsptr->tstate & 0xff);
+ trap_state* tsptr = cpu_tsptr(env);
+
+ env->pc = tsptr->tpc;
+ env->npc = tsptr->tnpc + 4;
+ PUT_CCR(env, tsptr->tstate >> 32);
+ env->asi = (tsptr->tstate >> 24) & 0xff;
+ change_pstate((tsptr->tstate >> 8) & 0xf3f);
+ PUT_CWP64(env, tsptr->tstate & 0xff);
env->tl--;
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
}
void helper_retry(void)
{
- env->pc = env->tsptr->tpc;
- env->npc = env->tsptr->tnpc;
- PUT_CCR(env, env->tsptr->tstate >> 32);
- env->asi = (env->tsptr->tstate >> 24) & 0xff;
- change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
- PUT_CWP64(env, env->tsptr->tstate & 0xff);
+ trap_state* tsptr = cpu_tsptr(env);
+
+ env->pc = tsptr->tpc;
+ env->npc = tsptr->tnpc;
+ PUT_CCR(env, tsptr->tstate >> 32);
+ env->asi = (tsptr->tstate >> 24) & 0xff;
+ change_pstate((tsptr->tstate >> 8) & 0xf3f);
+ PUT_CWP64(env, tsptr->tstate & 0xff);
env->tl--;
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
}
void helper_set_softint(uint64_t value)
@@ -3331,9 +3338,15 @@ static const char * const excp_names[0x8
};
#endif
+trap_state* cpu_tsptr(CPUState* env)
+{
+ return &env->ts[env->tl & MAXTL_MASK];
+}
+
void do_interrupt(CPUState *env)
{
int intno = env->exception_index;
+ trap_state* tsptr;
#ifdef DEBUG_PCALL
if (qemu_loglevel_mask(CPU_LOG_INT)) {
@@ -3390,13 +3403,14 @@ void do_interrupt(CPUState *env)
if (env->tl < env->maxtl)
env->tl++;
}
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
- env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
+ tsptr = cpu_tsptr(env);
+
+ tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
GET_CWP64(env);
- env->tsptr->tpc = env->pc;
- env->tsptr->tnpc = env->npc;
- env->tsptr->tt = intno;
+ tsptr->tpc = env->pc;
+ tsptr->tnpc = env->npc;
+ tsptr->tt = intno;
switch (intno) {
case TT_IVEC:
Index: qemu-trunk/target-sparc/helper.c
===================================================================
--- qemu-trunk.orig/target-sparc/helper.c
+++ qemu-trunk/target-sparc/helper.c
@@ -685,9 +685,10 @@ void cpu_reset(CPUSPARCState *env)
env->psrps = 1;
CC_OP = CC_OP_FLAGS;
#ifdef TARGET_SPARC64
- env->pstate = PS_PRIV;
+ env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
env->hpstate = HS_PRIV;
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
+ env->tl = env->maxtl;
+ cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
env->lsu = 0;
#else
env->mmuregs[0] &= ~(MMU_E | MMU_NF);
Index: qemu-trunk/target-sparc/machine.c
===================================================================
--- qemu-trunk.orig/target-sparc/machine.c
+++ qemu-trunk/target-sparc/machine.c
@@ -164,7 +164,6 @@ int cpu_load(QEMUFile *f, void *opaque,
qemu_get_be32s(f, &env->asi);
qemu_get_be32s(f, &env->pstate);
qemu_get_be32s(f, &env->tl);
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
qemu_get_be32s(f, &env->cansave);
qemu_get_be32s(f, &env->canrestore);
qemu_get_be32s(f, &env->otherwin);
Index: qemu-trunk/linux-user/main.c
===================================================================
--- qemu-trunk.orig/linux-user/main.c
+++ qemu-trunk/linux-user/main.c
@@ -962,7 +962,7 @@ void cpu_loop (CPUSPARCState *env)
if (trapnr == TT_DFAULT)
info._sifields._sigfault._addr = env->dmmuregs[4];
else
- info._sifields._sigfault._addr = env->tsptr->tpc;
+ info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
queue_signal(env, info.si_signo, &info);
}
break;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] sparc64 replace tsptr with helper routine
2009-07-20 19:00 ` Igor Kovalenko
@ 2009-07-21 7:21 ` Blue Swirl
0 siblings, 0 replies; 4+ messages in thread
From: Blue Swirl @ 2009-07-21 7:21 UTC (permalink / raw)
To: Igor Kovalenko; +Cc: qemu-devel
On Mon, Jul 20, 2009 at 10:00 PM, Igor
Kovalenko<igor.v.kovalenko@gmail.com> wrote:
> On Mon, Jul 20, 2009 at 10:49 AM, Blue Swirl<blauwirbel@gmail.com> wrote:
>> On Mon, Jul 20, 2009 at 12:19 AM, Igor
>> Kovalenko<igor.v.kovalenko@gmail.com> wrote:
>>> tl and tsptr of members sparc64 cpu state must be changed
>>> simultaneously to keep trap state window in sync with current
>>> trap level. Currently translation of store to tl does not change
>>> tsptr, which leads to corrupt trap state on corresponding
>>> trap level.
>>>
>>> This patch removes tsptr from sparc64 cpu state and replaces
>>> all uses with call to helper routine.
>>
>> I'd rather have the stores to TL fixed instead of introducing a
>> helper. A new function to set both TL and tsptr may help. Which stores
>> to TL do not change tsptr?
> The problem is with translate.c portion about handling wrpr
> (it sets tl only). My idea is that even remote possibility of tsptr
> and tl going out of sync guarantees killing one of them. Since
> tl is a real register I decided to loose tsptr.
Getting rid of env->tsptr is OK, but it seems pointless to introduce a
helper for such a small task. We could easily perform the get_tsptr
calculation at translation time.
>> On CPU reset, TL should be MAXTL for POR and MIN(TL+1, MAXTL) in other
>> cases but your patch would set it to 0.
>
> Right but please see that original code did not done that either :)
>
> Please see updated patch which additionally sets tl=maxtl.
> I decided to populate trap level, trap type and pstate with
> power-on reset values since other reset types are not handled yet.
Well, there is a kludge to handle the different PC for POR and others
in sun4u.c. Maybe this should be moved to helper.c and handled
properly with other reset type changes.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-07-21 7:21 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-19 21:19 [Qemu-devel] [PATCH] sparc64 replace tsptr with helper routine Igor Kovalenko
2009-07-20 6:49 ` Blue Swirl
2009-07-20 19:00 ` Igor Kovalenko
2009-07-21 7:21 ` Blue Swirl
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).